SEO & Meta Tags
Meta descriptions, Open Graph tags for social previews, canonical URLs, and structured data with JSON-LD.
Why <head> metadata matters beyond the browser tab
The introduction page in this track covered <title> and the viewport meta tag. There's a second layer of <head> metadata that never renders on the page at all, but directly shapes how a page appears in search results and when it's shared as a link on social media or in a chat app. None of it is required for a page to work — but skipping it means search engines and link-preview crawlers are left guessing at what the page is about.
The meta description
<meta name="description" content="Learn CSS Grid from scratch — template columns and rows, gap, named areas, and a full dashboard layout example.">
Search engines don't always use it verbatim (they sometimes generate a snippet from page content instead), but it's still the single most common source for the gray summary text shown under a search result's blue link. Keep it to roughly 150–160 characters — most search engines truncate beyond that — and write a genuine, specific summary of the page rather than a generic tagline repeated across every page on the site.
<meta name="robots" content="noindex, nofollow">
robots tells crawlers whether to index a page and whether to follow its links at all — useful for a staging environment, an internal admin page, or a duplicate/thank-you page you don't want appearing in search results.
Open Graph tags — controlling social link previews
Open Graph (originally a Facebook-authored standard, now used broadly by Slack, Discord, LinkedIn, iMessage, and most other platforms that render a link preview card) is a set of og:* meta tags describing how a URL should be represented when shared:
<meta property="og:title" content="CSS Grid — Full Tutorial">
<meta property="og:description" content="Learn CSS Grid from scratch, including a complete dashboard layout example.">
<meta property="og:image" content="https://noalabs.dev/images/css-grid-preview.png">
<meta property="og:url" content="https://noalabs.dev/tutorials/css/grid">
<meta property="og:type" content="article">
| Tag | Purpose |
|---|---|
og:title |
The headline shown on the preview card — can differ from <title> if a shorter, punchier version reads better as a card headline. |
og:description |
The card's body text. |
og:image |
The preview thumbnail. Aim for at least 1200×630px — most platforms crop or reject smaller images. |
og:url |
The canonical URL the card should link to, regardless of what URL variant (with tracking params, a trailing slash, etc.) was actually shared. |
og:type |
What kind of content this is (website, article, product) — some platforms adjust the card layout based on it. |
Twitter/X reads its own twitter:* tags first, falling back to Open Graph tags if they're absent — so it's worth adding a minimal Twitter Card block alongside Open Graph rather than assuming OG alone covers every platform:
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="CSS Grid — Full Tutorial">
<meta name="twitter:description" content="Learn CSS Grid from scratch, including a complete dashboard layout example.">
<meta name="twitter:image" content="https://noalabs.dev/images/css-grid-preview.png">
Canonical URLs
<link rel="canonical" href="https://noalabs.dev/tutorials/css/grid">
A canonical URL tells search engines "if you find this same content reachable at several different URLs, treat this one as the authoritative version." This matters more than it might seem — the same page is often reachable through more than one URL without anyone intending it: https:// vs a legacy http:// redirect, with and without a trailing slash, with tracking query parameters (?utm_source=twitter) appended, or a paginated/filtered view of content that's otherwise identical to the main page. Without a canonical tag, a search engine may treat these as separate, competing pages — diluting ranking signals that should all be consolidated onto one URL — or simply pick whichever version it happens to have crawled first, which might not be the one you'd choose.
Structured data with JSON-LD, briefly
Structured data is a machine-readable description of a page's content, embedded using the schema.org vocabulary — most commonly as a <script type="application/ld+json"> block. It's what powers "rich results" in search — star ratings under a recipe, a FAQ dropdown directly in search results, an event's date and venue shown inline:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "CSS Grid — Full Tutorial",
"author": {
"@type": "Organization",
"name": "NOA Labs"
},
"datePublished": "2026-08-26"
}
</script>
This isn't rendered visually at all — it exists purely for machines parsing the page. A full treatment of schema.org's vocabulary (there are types for articles, products, recipes, events, FAQs, and dozens more, each with their own expected fields) is a large topic on its own; the takeaway here is just that this is the mechanism, JSON-LD is the format search engines now prefer over the older inline itemprop microdata syntax, and it's additive — it never replaces writing good visible content, only supplements it with an explicit, structured summary a crawler doesn't have to guess at.
A complete example <head>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS Grid — Full Tutorial | NOA Labs</title>
<meta name="description" content="Learn CSS Grid from scratch — template columns and rows, gap, named areas, and a full dashboard layout example.">
<link rel="canonical" href="https://noalabs.dev/tutorials/css/grid">
<meta property="og:title" content="CSS Grid — Full Tutorial">
<meta property="og:description" content="Learn CSS Grid from scratch, including a complete dashboard layout example.">
<meta property="og:image" content="https://noalabs.dev/images/css-grid-preview.png">
<meta property="og:url" content="https://noalabs.dev/tutorials/css/grid">
<meta property="og:type" content="article">
<meta name="twitter:card" content="summary_large_image">
</head>
Common mistakes
- Writing one generic
<meta name="description">and copy-pasting it across every page on a site — search engines and social previews then show the same summary regardless of what page was actually shared, which looks broken and hurts click-through. - Forgetting
og:image— many platforms fall back to rendering a link with no thumbnail at all, which gets noticeably less engagement than a card with a real preview image. - Setting a canonical URL that points somewhere other than the page itself by accident (a common copy-paste bug across templated pages) — this actively tells search engines to ignore the current page in favor of a different one.
- Assuming JSON-LD structured data guarantees a rich result — it makes a page eligible, but search engines still decide independently whether and how to display any enhanced result.