Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions site/catalog.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
<title>Lesson Catalog - Course: Computer Science</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' fill='%23FFF7EC'/><rect x='2' y='2' width='28' height='28' fill='none' stroke='%23E2557A' stroke-width='1.2'/><text x='6' y='22' font-size='14' font-family='monospace' fill='%23E2557A'>CS</text></svg>">
<meta name="description" content="Full catalog of 421 computer science lessons. Search, filter, and sort every lesson across all 20 phases.">
<link rel="canonical" href="https://course-computer-science.riteshrana.engineer/catalog.html">
<meta property="og:title" content="Catalog · Course: Computer Science">
<meta property="og:description" content="Search and filter 421 lessons across 20 phases, from discrete math to distributed systems.">
<meta property="og:image" content="og-image.svg">
<meta property="og:url" content="/catalog.html">
<meta property="og:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<meta property="og:url" content="https://course-computer-science.riteshrana.engineer/catalog.html">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Catalog · Course: Computer Science">
<meta name="twitter:description" content="Search and filter 421 lessons across 20 phases.">
<meta name="twitter:image" content="og-image.svg">
<meta name="twitter:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
Expand Down
7 changes: 4 additions & 3 deletions site/glossary.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
<title>CS Glossary - Course: Computer Science</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' fill='%23FFF7EC'/><rect x='2' y='2' width='28' height='28' fill='none' stroke='%23E2557A' stroke-width='1.2'/><text x='6' y='22' font-size='14' font-family='monospace' fill='%23E2557A'>CS</text></svg>">
<meta name="description" content="CS glossary: what people say vs what things actually mean. Every term explained without hand-waving.">
<link rel="canonical" href="https://course-computer-science.riteshrana.engineer/glossary.html">
<meta property="og:title" content="Glossary · Course: Computer Science">
<meta property="og:description" content="What people say vs what things actually mean. Every computer science term, defined without hand-waving.">
<meta property="og:image" content="og-image.svg">
<meta property="og:url" content="/glossary.html">
<meta property="og:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<meta property="og:url" content="https://course-computer-science.riteshrana.engineer/glossary.html">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Glossary · Course: Computer Science">
<meta name="twitter:description" content="What people say vs what things actually mean.">
<meta name="twitter:image" content="og-image.svg">
<meta name="twitter:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
Expand Down
7 changes: 4 additions & 3 deletions site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
<title>Course: Computer Science</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' fill='%23FFF7EC'/><rect x='2' y='2' width='28' height='28' fill='none' stroke='%23E2557A' stroke-width='1.2'/><text x='5' y='22' font-size='14' font-family='monospace' fill='%23E2557A'>CS</text></svg>">
<meta name="description" content="421 lessons. 20 phases. Build the algorithms, memory models, operating systems, compilers, networks, databases, and distributed systems by hand.">
<link rel="canonical" href="https://course-computer-science.riteshrana.engineer/">
<meta property="og:title" content="Course: Computer Science">
<meta property="og:description" content="421 lessons. 20 phases. Build the machine from discrete math through distributed systems. C, C++, Rust, Go, Python, Haskell, SQL, RISC-V assembly, and TLA+.">
<meta property="og:image" content="og-image.svg">
<meta property="og:url" content="/">
<meta property="og:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<meta property="og:url" content="https://course-computer-science.riteshrana.engineer/">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Course: Computer Science">
<meta name="twitter:description" content="421 lessons. 20 phases. Build computer science from first principles.">
<meta name="twitter:image" content="og-image.svg">
<meta name="twitter:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
Expand Down
4 changes: 2 additions & 2 deletions site/lesson.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
<meta name="description" content="A lesson from the Course: Computer Science curriculum. 421 lessons across 20 phases, from discrete math to distributed systems.">
<meta property="og:title" content="Course: Computer Science · Lesson">
<meta property="og:description" content="421 lessons. 20 phases. Build core computer science artifacts by hand, from allocators to distributed protocols.">
<meta property="og:image" content="og-image.svg">
<meta property="og:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<!-- og:url omitted intentionally: lesson.html is a static template that loads the lesson body client-side via ?path=. Static hosting cannot template the URL, so we let crawlers fall back to the request URL (which is the lesson-specific share link). -->
<meta property="og:type" content="article">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Course: Computer Science">
<meta name="twitter:description" content="421 lessons. 20 phases. Build it from first principles, by hand.">
<meta name="twitter:image" content="og-image.svg">
<meta name="twitter:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
Expand Down
Binary file added site/og-image-1200x630.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions site/og-image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions site/prereqs.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
<title>Roadmap - Course: Computer Science</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' fill='%23FFF7EC'/><rect x='2' y='2' width='28' height='28' fill='none' stroke='%23E2557A' stroke-width='1.2'/><text x='6' y='22' font-size='14' font-family='monospace' fill='%23E2557A'>CS</text></svg>">
<meta name="description" content="Interactive prerequisite map for 421 computer science lessons. See which phases depend on which, and plan your learning path.">
<link rel="canonical" href="https://course-computer-science.riteshrana.engineer/prereqs.html">
<meta property="og:title" content="Roadmap · Course: Computer Science">
<meta property="og:description" content="Interactive prerequisite map. See what each phase depends on and what it unlocks downstream.">
<meta property="og:image" content="og-image.svg">
<meta property="og:url" content="/prereqs.html">
<meta property="og:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<meta property="og:url" content="https://course-computer-science.riteshrana.engineer/prereqs.html">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Roadmap · Course: Computer Science">
<meta name="twitter:description" content="Interactive prerequisite map across 20 phases.">
<meta name="twitter:image" content="og-image.svg">
<meta name="twitter:image" content="https://course-computer-science.riteshrana.engineer/og-image-1200x630.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
Expand Down
38 changes: 38 additions & 0 deletions tests/social-preview.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');

const SITE = path.join(__dirname, '..', 'site');
const ORIGIN = 'https://course-computer-science.riteshrana.engineer';
const IMAGE = `${ORIGIN}/og-image-1200x630.png`;

for (const page of ['index.html', 'catalog.html', 'glossary.html', 'prereqs.html', 'lesson.html']) {
test(`${page} shares the raster preview image`, () => {
const html = fs.readFileSync(path.join(SITE, page), 'utf8');
assert.match(html, /<meta property="og:title" content="[^"]+">/);
assert.ok(html.includes(`<meta property="og:image" content="${IMAGE}">`));
assert.ok(html.includes(`<meta name="twitter:image" content="${IMAGE}">`));
});
}

for (const [page, pathname] of [
['index.html', '/'],
['catalog.html', '/catalog.html'],
['glossary.html', '/glossary.html'],
['prereqs.html', '/prereqs.html'],
]) {
test(`${page} uses its absolute canonical URL`, () => {
const html = fs.readFileSync(path.join(SITE, page), 'utf8');
const expected = `${ORIGIN}${pathname}`;
assert.ok(html.includes(`<link rel="canonical" href="${expected}">`));
assert.ok(html.includes(`<meta property="og:url" content="${expected}">`));
});
}

test('social preview is a 1200 by 630 PNG', () => {
const png = fs.readFileSync(path.join(SITE, 'og-image-1200x630.png'));
assert.equal(png.subarray(0, 8).toString('hex'), '89504e470d0a1a0a');
assert.equal(png.readUInt32BE(16), 1200);
assert.equal(png.readUInt32BE(20), 630);
});
Loading