Technical SEO markup beyond the basics you met in the intro series: canonical URLs, hreflang for language variants, and structured data at a level that helps search engines without turning every page into JSON-LD soup. Is one of those topics that pays off as soon as you use it on a real page.
Canonical URLs
When the same content is reachable at multiple URLs (tracking parameters, HTTP vs HTTPS, www vs bare domain, pagination quirks), pick one canonical URL and say so in <head>:
<link rel="canonical" href="https://codeskill.co.uk/html/advanced/seo/">
The canonical should be an absolute URL. It does not redirect users – it hints to crawlers which URL to index. Fix duplicate content in routing and redirects too; the link element is not a substitute for proper server configuration.
hreflang for language and region
If you publish the same page in multiple languages or regional variants, hreflang tells search engines which URL serves which audience:
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/pricing/">
<link rel="alternate" hreflang="en-US" href="https://example.com/us/pricing/">
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing/">
Each language version should reference all others, including itself. Use valid BCP 47 language tags (en-GB, not uk). x-default is the fallback when no other tag matches. Broken hreflang (missing return links, wrong codes) wastes everyone’s time – validate in Search Console when you ship it.
Robots and indexing hints
<meta name="robots" content="noindex, nofollow">
<meta name="robots" content="max-snippet:-1, max-image-preview:large">
Use noindex on staging, thin utility pages, and duplicate faceted URLs – but prefer fixing the root cause. X-Robots-Tag HTTP headers work for non-HTML resources. Do not block CSS and JS in robots.txt; crawlers need them to understand the page.
Structured data beyond basics
JSON-LD in a script block keeps structured data separate from visible markup. Build on the intermediate microdata lesson with graph-style objects for articles, courses, and breadcrumbs:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Course",
"name": "Going deep with HTML",
"description": "Going deep with HTML on Codeskill",
"provider": {
"@type": "Organization",
"name": "Codeskill",
"url": "https://codeskill.co.uk"
}
}
</script>
Only mark up content that is visible and true. Google rich results require specific required fields – check the documentation for each type. Invalid or misleading schema can trigger manual actions. One well-formed block beats five redundant formats (JSON-LD plus microdata plus RDFa for the same thing).
Open Graph and social previews
<meta property="og:title" content="Going deep with HTML">
<meta property="og:description" content="Advanced HTML tutorials on Codeskill.">
<meta property="og:url" content="https://codeskill.co.uk/html/advanced/">
<meta property="og:image" content="https://codeskill.co.uk/img/og/html-advanced.jpg">
<meta name="twitter:card" content="summary_large_image">
These tags do not replace good titles and meta descriptions for search, but they control how links look when shared. Use absolute URLs for og:url and og:image. Keep image dimensions sensible (often 1200×630 for large cards).
HTML that still matters for SEO
One <h1> per page that matches intent. Descriptive <title> unique across the site. Real text in <main>, not only in images. Clean internal links with understandable anchor text. Technical tags amplify good content; they do not rescue empty pages.

