SEO, Meta Tags & Structured Data
SEO is not a marketing concern — it's an engineering discipline. The <head> of your document is an API contract with search engines, social platforms, and browsers. Senior engineers understand exactly which meta tags matter, how structured data drives rich results, and why Core Web Vitals are an engineering responsibility.
Essential Meta Tags
Every page should include these baseline meta tags:
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Learn Web Components — the browser's
native component model for building encapsulated, reusable UI." />
<meta name="robots" content="index, follow" />
<title>Web Components Guide | Frontend Dinosaur</title>
</head>| Meta Tag | Purpose | Impact |
|---|---|---|
charset | Character encoding | Must be first — prevents encoding attacks (UTF-7 XSS) |
viewport | Responsive viewport | Required for mobile rendering; Google uses mobile-first indexing |
description | Page summary | Appears as snippet in search results (150-160 chars) |
robots | Crawler directives | Controls indexing and following links |
<title> | Page title | Most important on-page SEO signal; appears in browser tab and SERPs |
robots Meta Directives
<!-- Default: index and follow all links -->
<meta name="robots" content="index, follow" />
<!-- Don't index, but follow links (useful for staging or thin pages) -->
<meta name="robots" content="noindex, follow" />
<!-- Index page but don't follow any links -->
<meta name="robots" content="index, nofollow" />
<!-- Don't show cached version -->
<meta name="robots" content="noarchive" />
<!-- Don't show snippet in results -->
<meta name="robots" content="nosnippet" />
<!-- Target specific crawlers -->
<meta name="googlebot" content="noindex" />robots.txt vs meta robots:
robots.txtprevents crawling (bot never sees the page)<meta name="robots">allows crawling but controls indexing- A page blocked by
robots.txtcan still appear in results if other pages link to it
Open Graph Protocol
Open Graph tags control how your page appears when shared on social platforms:
<meta property="og:title" content="Web Components Guide" />
<meta property="og:description" content="Build encapsulated, reusable
UI components with the browser's native API." />
<meta property="og:image" content="https://example.com/og-image.png" />
<meta property="og:url" content="https://example.com/web-components" />
<meta property="og:type" content="article" />
<meta property="og:site_name" content="Frontend Dinosaur" />
<meta property="og:locale" content="en_US" />Image requirements for optimal display:
- Minimum: 1200×630px (Facebook, LinkedIn)
- Aspect ratio: 1.91:1
- File size: under 8MB
- Format: PNG or JPG (avoid SVG — many platforms don't render it)
Twitter Cards
Twitter uses its own meta tags, falling back to Open Graph:
<!-- summary_large_image shows a large preview image -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@frontenddinosaur" />
<meta name="twitter:creator" content="@authorhandle" />
<meta name="twitter:title" content="Web Components Guide" />
<meta name="twitter:description" content="Build encapsulated UI components." />
<meta name="twitter:image" content="https://example.com/twitter-card.png" />| Card Type | Image Size | Use Case |
|---|---|---|
summary | 120×120 to 4096×4096 | Default; small thumbnail |
summary_large_image | 300×157 to 4096×4096 | Articles, visual content |
player | — | Video/audio embeds |
app | — | Mobile app install cards |
Canonical URLs
Canonical tags tell search engines which URL is the "master" version when content exists at multiple URLs:
<!-- On https://example.com/blog/web-components?ref=twitter -->
<link rel="canonical" href="https://example.com/blog/web-components" />When canonicals matter:
- URL parameters (
?sort=date,?ref=newsletter) creating duplicate pages - HTTP vs HTTPS versions
- www vs non-www
- Mobile (m.example.com) vs desktop versions
- Paginated content
- Content syndicated across multiple sites
Without canonicals, search engines split ranking authority across duplicates — diluting your page's power.
Internationalization: hreflang
For multi-language sites, hreflang tells search engines which version to show based on user locale:
<link rel="alternate" hreflang="en" href="https://example.com/en/guide" />
<link rel="alternate" hreflang="es" href="https://example.com/es/guide" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/guide" />
<link rel="alternate" hreflang="x-default" href="https://example.com/guide" />Rules:
- Every page must link to ALL its language variants (including itself)
x-defaultis the fallback for unmatched locales- Use ISO 639-1 language codes, optionally with ISO 3166-1 region:
en-US,pt-BR - Bidirectional: if page A links to page B, page B must link back to page A
Structured Data: JSON-LD
JSON-LD (JavaScript Object Notation for Linked Data) is Google's preferred format for structured data. It powers rich results — star ratings, FAQ accordions, recipe cards, event listings:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Web Components & Shadow DOM",
"author": {
"@type": "Person",
"name": "Sarah Chen",
"url": "https://example.com/authors/sarah-chen"
},
"publisher": {
"@type": "Organization",
"name": "Frontend Dinosaur",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"datePublished": "2025-01-15",
"dateModified": "2025-03-01",
"description": "Build encapsulated UI components with the browser's native API.",
"image": "https://example.com/web-components-hero.png"
}
</script>Common Schema.org Types
| Type | Rich Result | Key Properties |
|---|---|---|
Article | News/blog article card | headline, author, datePublished |
FAQPage | Expandable FAQ in search | mainEntity (array of Questions) |
HowTo | Step-by-step guide | step (array of HowToSteps) |
Product | Product card with price | name, offers, aggregateRating |
BreadcrumbList | Breadcrumb trail in SERP | itemListElement |
Organization | Knowledge panel | name, logo, sameAs (social links) |
LocalBusiness | Local business card | address, openingHours, geo |
Validation: Always test structured data with Google's Rich Results Test (search.google.com/test/rich-results) before deploying.
Sitemap & robots.txt
robots.txt
User-agent: *
Disallow: /admin/
Disallow: /api/
Disallow: /staging/
Allow: /api/public/
Sitemap: https://example.com/sitemap.xmlsitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://example.com/web-components</loc>
<lastmod>2025-03-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://example.com/accessibility</loc>
<lastmod>2025-02-15</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
</urlset>Priority is relative within your site — it doesn't affect ranking against other sites. Use 1.0 for homepage, 0.8 for key content, 0.5 for supporting pages.
Core Web Vitals & SEO
Google uses Core Web Vitals as ranking signals:
| Metric | Measures | Good | Needs Improvement | Poor |
|---|---|---|---|---|
| LCP (Largest Contentful Paint) | Loading speed | ≤ 2.5s | ≤ 4.0s | > 4.0s |
| INP (Interaction to Next Paint) | Responsiveness | ≤ 200ms | ≤ 500ms | > 500ms |
| CLS (Cumulative Layout Shift) | Visual stability | ≤ 0.1 | ≤ 0.25 | > 0.25 |
HTML-level optimizations that impact CWV:
<!-- LCP: Preload the largest content element -->
<link rel="preload" as="image" href="/hero.webp"
fetchpriority="high" />
<!-- CLS: Always set dimensions on images -->
<img src="/hero.webp" width="1200" height="630" alt="Hero image"
loading="eager" decoding="async" />
<!-- CLS: Reserve space for dynamic content -->
<div style="aspect-ratio: 16/9;">
<iframe src="..." loading="lazy"></iframe>
</div>Performance Hints in the <head>
Resource hints tell the browser to start work early:
<!-- dns-prefetch: Resolve DNS for third-party domains -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
<!-- preconnect: DNS + TCP + TLS handshake (stronger than dns-prefetch) -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<!-- preload: Download critical resources ASAP -->
<link rel="preload" as="font" type="font/woff2" crossorigin
href="/fonts/inter.woff2" />
<!-- prefetch: Download resources for NEXT navigation -->
<link rel="prefetch" href="/next-page.html" />
<!-- modulepreload: Preload ES modules -->
<link rel="modulepreload" href="/js/app.mjs" />| Hint | When | Priority | Use Case |
|---|---|---|---|
dns-prefetch | Resolve DNS early | Low | Third-party analytics, CDNs |
preconnect | Full connection early | Medium | Fonts, API servers, CDNs |
preload | Download now | High | Fonts, hero images, critical CSS |
prefetch | Download for later | Idle | Next page's resources |
modulepreload | Load + parse JS module | High | Critical JavaScript modules |
Favicon & Web App Manifest
<!-- Modern favicon approach -->
<link rel="icon" href="/favicon.ico" sizes="32x32" />
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<!-- Web App Manifest -->
<link rel="manifest" href="/manifest.json" />The manifest (manifest.json) enables "Add to Home Screen" and controls standalone app appearance — defining name, icons, theme_color, start_url, and display mode.
Semantic HTML's Impact on Rankings
Search engines increasingly use content semantics for ranking:
<article>signals primary content vs boilerplate<nav>helps identify navigation (often de-weighted in content analysis)<main>tells crawlers where the primary content lives- Heading hierarchy (
h1→h2→h3) structures topic relevance <time datetime="...">provides unambiguous date parsing
<!-- Search engine can parse this date regardless of display format -->
<time datetime="2025-01-15T09:00:00Z">January 15th</time>
<!-- Without <time>, "January 15th" is ambiguous -->
<span>January 15th</span> <!-- Which year? What timezone? -->Interview Mental Model
SEO Engineering Stack
├── <head> Contract → title, description, canonical, viewport, robots
├── Social Sharing → Open Graph (Facebook/LinkedIn), Twitter Cards
├── Structured Data → JSON-LD with Schema.org vocabulary
├── Discoverability → sitemap.xml, robots.txt, hreflang
├── Performance Signals → Core Web Vitals (LCP, INP, CLS)
└── Resource Hints → preconnect, preload, prefetch, dns-prefetch
Key principle: Every tag in <head> is a machine-readable instruction.
There are no optional tags — only tags you haven't needed yet.When asked about SEO in interviews, don't talk about keywords and backlinks — that's marketing. Talk about the technical contract: how your HTML communicates with crawlers, how structured data earns rich results, how Core Web Vitals reflect engineering quality, and how semantic markup provides machine-readable meaning. That's the senior engineering answer.