SEO — Sitemap, Robots, OpenGraph, and Structured Data

Complete guide to search engine optimization in Dax Pro: auto-generated sitemap.xml, robots.txt, RSS feed, OpenGraph and Twitter Card meta tags, JSON-LD structured data, canonical URLs, and how to submit your site to Google Search Console and Bing Webmaster Tools.

What SEO Means for a Static Site

Search engine optimization is the practice of making your site easy for search engines to crawl, understand, and rank. For a static site built with Dax Pro, most of the work is already done:

  • The HTML is real. Every page is a complete HTML document, not an empty shell populated by JavaScript.
  • The build is fast. Pages are served as static files from a CDN, typically in under 50 milliseconds.
  • The markup is semantic. Headings are real

    ,

    ; navigation is real

  • There is no client-side routing. Every URL returns a complete page. No 404s for internal navigation.
  • There is no hydration. Crawlers see the same page users see, immediately.
  • These properties already put Dax Pro ahead of most dynamic sites on the technical side of SEO. But technical SEO is only half the story. The other half is metadata: titles, descriptions, canonical URLs, structured data, and the files search engines use to discover and index your content.

    Dax Pro generates all of this automatically. But you must configure it correctly for it to work.

    This chapter covers:

    1. What Dax Pro generates automatically — sitemap, robots.txt, RSS

    2. The seo.dax partial — the metadata that appears on every page

    3. Canonical URLs — the most important SEO field and the most commonly broken

    4. OpenGraph and Twitter Cards — how your site appears when shared

    5. JSON-LD structured data — how search engines understand your content

    6. Google Search Console — how to tell Google about your site

    7. Bing Webmaster Tools — the same for Bing

    8. Verifying SEO — how to check your work


    What Dax Pro Generates Automatically

    On every build, Dax Pro writes three SEO files to site/:

    sitemap.xml

    A list of every URL on your site, in XML format. Search engines use this to discover pages they might not have crawled otherwise.

    Location: site/sitemap.xml

    Public URL: https://yourdomain.com/sitemap.xml

    Format:

    <?xml version="1.0" encoding="UTF-8"?>
    

    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

    <url><loc>https://yourdomain.com/</loc></url>

    <url><loc>https://yourdomain.com/about/</loc></url>

    <url><loc>https://yourdomain.com/posts/</loc></url>

    <url><loc>https://yourdomain.com/posts/why-static-sites-win/</loc></url>

    ...

    </urlset>

    One entry per URL. The sitemap includes every page, post, service, tag page, and listing page. It is generated from the list of files that were built.

    No configuration needed. The sitemap is built automatically. You do not need to add pages to it or maintain it manually.

    robots.txt

    Instructions for search engine crawlers.

    Location: site/robots.txt

    Public URL: https://yourdomain.com/robots.txt

    Format:

    User-agent: *
    

    Allow: /

    Sitemap: https://yourdomain.com/sitemap.xml

    What it says:

  • User-agent: * — applies to all crawlers
  • Allow: / — allow crawling of every path
  • Sitemap: ... — tells crawlers where to find the sitemap
  • No configuration needed. The robots.txt is generated automatically. It points to your sitemap, so search engines discover the sitemap on their first crawl.

    If you want to block search engines entirely (for a staging site, for example), edit robots.txt in the repository. But be careful — blocking a production site removes it from search results.

    rss.xml

    An RSS feed of your latest posts.

    Location: site/rss.xml

    Public URL: https://yourdomain.com/rss.xml

    Format: Standard RSS 2.0 with the 20 most recent posts.

    What it includes: title, link, and GUID for each post. The RSS feed is used by feed readers (Feedly, Inoreader, NetNewsWire) and by some search engines.

    Linked from every page. The of every page includes:

    <link rel="alternate" type="application/rss+xml" title="..." href="/rss.xml">
    

    This tells feed readers and browsers that an RSS feed exists.

    No configuration needed. The RSS feed is generated automatically.


    The seo.dax Partial

    The seo.dax partial is included in base.dax and renders on every page. It outputs all the metadata tags that search engines and social platforms read.

    Location: templates/partials/shared/seo.dax

    What it renders:

    <meta name="generator" content="DAX dotnet - Pure C# Slim SSG">
    

    <title>Page Title</title>

    <meta name="description" content="Page description">

    <link rel="canonical" href="https://yourdomain.com/page-url/">

    <meta property="og:type" content="article">

    <meta property="og:site_name" content="Dax Pro">

    <meta property="og:title" content="Page Title">

    <meta property="og:description" content="Page description">

    <meta property="og:url" content="https://yourdomain.com/page-url/">

    <meta property="og:image" content="https://yourdomain.com/images/og-image.jpg">

    <meta property="og:image:alt" content="Page Title">

    <meta name="twitter:card" content="summary_large_image">

    <meta name="twitter:title" content="Page Title">

    <meta name="twitter:description" content="Page description">

    <meta name="twitter:image" content="https://yourdomain.com/images/og-image.jpg">

    <meta name="twitter:image:alt" content="Page Title">

    <link href="/favicon.ico" rel="icon" type="image/x-icon">

    <script type="application/ld+json">

    {

    "@context": "https://schema.org",

    "@type": "Article",

    "headline": "Page Title",

    ...

    }

    </script>

    Every tag is derived from frontmatter and _data/metadata.yaml.

    Do not modify seo.dax unless you are a developer with a specific SEO requirement. The default partial follows search engine best practices. Changes should be deliberate and tested.


    Canonical URLs — The Most Important Field

    The canonical URL tells search engines which URL is the "real" one for a given piece of content. It is the single most important SEO field and the most commonly broken.

    The canonical URL is composed of two parts:

    1. metadata.url — the site's base URL

    2. url — the current page's path

    Together they form the canonical URL:

    {metadata.url}{url}
    

    Example:

  • metadata.url = https://yourdomain.com
  • url = /posts/why-static-sites-win/
  • Canonical = https://yourdomain.com/posts/why-static-sites-win/
  • Rules:

  • metadata.url must not end with a slash. https://yourdomain.com ✓, https://yourdomain.com/ ✗
  • url always starts with a slash. /about/, /posts/my-post/ ✓
  • The canonical must be absolute. https://..., not /about/
  • Why this matters: search engines treat https://example.com/about/, http://example.com/about/, https://www.example.com/about/, and https://example.com/about as four different URLs. Without canonical tags, they might index all four and see duplicate content. The canonical tag says "the real one is this one." Search engines consolidate ranking signals to the canonical URL.

    Configuring metadata.url:

    In _data/metadata.yaml:

    url: "https://yourdomain.com"
    

    After connecting a custom domain, update this field. If it says https://your-site.netlify.app but the site is live at https://yourdomain.com, search engines are told to index the wrong domain.

    Verifying canonical URLs:

    1. Open any page in a browser

    2. View source (Ctrl + U or Cmd + U)

    3. Search for rel="canonical"

    4. Confirm the URL matches the page's actual URL

    If the canonical URL does not match, metadata.url is wrong or the seo.dax partial has been modified incorrectly.


    OpenGraph and Twitter Cards

    When someone shares your page on social media, the platform reads specific meta tags to generate the preview. These tags control:

  • The title of the preview
  • The description
  • The image
  • The URL
  • Dax Pro generates both OpenGraph (Facebook, LinkedIn, Slack, Discord) and Twitter Card tags automatically.

    OpenGraph tags

    Tag Source Purpose
    og:type Conditional — article for posts, website otherwise Content type
    og:site_name metadata.title Site name
    og:title Page title Preview title
    og:description Page description Preview description
    og:url Canonical URL Preview URL
    og:image Page image or metadata.image Preview image
    og:image:alt Page title Image alt text

    Twitter Card tags

    Tag Source Purpose
    twitter:card Fixed — summary_large_image Card style
    twitter:title Page title Card title
    twitter:description Page description Card description
    twitter:image Page image or metadata.image Card image
    twitter:image:alt Page title Image alt text

    The og:image and twitter:image are the most important. They control what image appears in the preview. If they are missing or broken, the preview shows no image — reducing click-through rate.

    Configuring the image:

    For the site default:

    # _data/metadata.yaml
    

    image: "/images/og-default.jpg"

    For a specific page:

    # In the post frontmatter
    

    image: "https://images.unsplash.com/photo-1234567890?w=1200&q=80&auto=format&fit=crop"

    The image should be:

  • 1200 × 630 pixels — the standard for Twitter and Facebook
  • Under 200 KB — larger images may not be fetched by some platforms
  • Accessible — publicly reachable via HTTPS
  • Relevant to the content — the same image on every page is not as effective as page-specific images
  • Testing the preview:

    1. Open opengraph.xyz

    2. Paste your page URL

    3. The tool shows a preview of how the page appears on Facebook, Twitter, LinkedIn, and Slack

    4. If the preview is wrong, the meta tags are wrong

    Alternatively:

  • Facebook Debugger — developers.facebook.com/tools/debug
  • Twitter Card Validator — cards-dev.twitter.com/validator
  • LinkedIn Post Inspector — linkedin.com/post-inspector
  • Each platform caches previews for a while. After changing meta tags, you may need to force a re-fetch by re-submitting the URL to the debugger.


    JSON-LD Structured Data

    JSON-LD is a format for embedding structured data in HTML. It tells search engines what kind of content the page contains — an article, a product, an event, a recipe — and provides structured fields for that content.

    Dax Pro generates JSON-LD on every page automatically. The default schema:

    For posts and articles:

    {
    

    "@context": "https://schema.org",

    "@type": "Article",

    "headline": "Post Title",

    "description": "Post description",

    "url": "https://yourdomain.com/posts/my-post/",

    "image": "https://yourdomain.com/images/post-image.jpg",

    "datePublished": "2026-05-19",

    "author": {

    "@type": "Person",

    "name": "Author Name"

    },

    "publisher": {

    "@type": "Organization",

    "name": "Dax Pro",

    "logo": {

    "@type": "ImageObject",

    "url": "https://yourdomain.com/favicon.ico"

    }

    }

    }

    For other pages:

    {
    

    "@context": "https://schema.org",

    "@type": "WebSite",

    ...

    }

    What this does: search engines use JSON-LD to understand the content. For articles, Google may display the publication date and author in search results (the "rich snippet"). For pages with reviews, Google may display star ratings. For product pages, Google may display price and availability.

    Dax Pro's default schema is Article and WebSite only. This covers the most common use cases. If you need richer schemas — Product, FAQPage, HowTo, Recipe — you must extend seo.dax. This is a developer task, covered in the Developer Guide.

    Validating JSON-LD:

    1. Open search.google.com/test/rich-results

    2. Enter your page URL

    3. Google tests whether the structured data is valid and what rich results it would produce

    4. If there are errors, they are shown with specific line numbers

    Common JSON-LD issues:

  • Missing required fields — Article requires headline, image, datePublished, author. If any is missing, validation fails.
  • Malformed JSON — a missing comma or unmatched quote. Search engines ignore malformed JSON-LD.
  • Wrong @type — a blog post should be Article, not WebPage. A homepage should be WebSite, not Article.
  • Dax Pro's default seo.dax handles these correctly for post and page types. If you extend the schema, test with the Rich Results tool.


    Google Search Console

    Google Search Console is the official tool for telling Google about your site. It is free, and it is the single most useful SEO tool you can use.

    Step 1: Sign up

    1. Open search.google.com/search-console

    2. Sign in with your Google account

    3. Click Add Property

    4. Choose Domain (recommended) or URL prefix

    Domain verification covers all subdomains and protocols (https://, http://, www, and non-www). It requires a DNS TXT record.

    URL prefix verification covers only the exact prefix specified. It is easier to set up (HTML file, meta tag, or DNS record).

    For Dax Pro, use URL prefix with the HTML tag method. It is the fastest.

    Step 2: Verify with an HTML meta tag

    1. After adding the property, Google gives you a meta tag:

    <meta name="google-site-verification" content="abc123...">
    

    2. Add this tag to templates/partials/shared/seo.dax:

    <meta name="google-site-verification" content="abc123...">
    

    3. Rebuild and deploy

    4. Return to Search Console and click Verify

    Google fetches the page and checks for the tag. If it is present, verification succeeds.

    Alternative: verify via DNS. Add a TXT record provided by Google to your DNS provider. This is the recommended method for domain properties but requires DNS access.

    Step 3: Submit the sitemap

    1. In Search Console, click Sitemaps in the left sidebar

    2. Enter sitemap.xml

    3. Click Submit

    4. Google queues the sitemap for processing

    Within a few minutes, Search Console shows the sitemap status. Within a few days, Google crawls the URLs in the sitemap and begins indexing them.

    What you can do with Search Console:

  • See which pages are indexed — the "Pages" report shows which URLs Google has indexed and which have issues
  • See search queries — the "Performance" report shows which queries triggered your site in search results, how many impressions, and how many clicks
  • See technical issues — coverage errors, mobile usability problems, Core Web Vitals
  • Request re-indexing — after updating a page, request that Google re-crawl it (the "URL Inspection" tool)
  • Check Search Console weekly for the first month after launch. It reveals problems you cannot see from the site itself.


    Bing Webmaster Tools

    Bing Webmaster Tools is the equivalent for Bing (which also powers DuckDuckGo and Yahoo). The process is similar to Google Search Console.

    Step 1: Sign up

    1. Open bing.com/webmasters

    2. Sign in with a Microsoft account (any email works, or use Google)

    3. Click Add site

    4. Enter your site URL

    Step 2: Verify

    Bing offers multiple verification methods:

  • XML file — download a file, place it at your site root
  • Meta tag — add to seo.dax (same as Google)
  • CNAME record — DNS-based verification
  • Import from Google Search Console — the easiest if you already have Google set up
  • The import method uses Google's verification. If your site is verified in Search Console, Bing can verify automatically.

    Step 3: Submit the sitemap

    1. In Bing Webmaster Tools, click Sitemaps

    2. Enter sitemap.xml

    3. Click Submit

    Bing crawls the sitemap and indexes URLs. The Bing index is much smaller than Google's, but for sites targeting global audiences, it is worth the five minutes to set up.


    Verifying SEO

    After configuring and deploying, verify that everything works.

    Sitemap

    1. Open https://yourdomain.com/sitemap.xml in a browser

    2. Confirm the file loads (not a 404)

    3. Confirm it lists multiple URLs

    4. Confirm the URLs start with https://yourdomain.com/ (not http://, not the Netlify subdomain)

    5. Confirm the sitemap does not include build artifacts (/site/, /admin/, /sitemap.xml itself)

    If the sitemap has wrong URLs, metadata.url is wrong. Update _data/metadata.yaml and rebuild.

    Robots

    1. Open https://yourdomain.com/robots.txt

    2. Confirm it loads

    3. Confirm it has Allow: /

    4. Confirm the sitemap URL is correct

    Canonical

    1. Open any page

    2. View source

    3. Confirm points to the page's actual URL (not the Netlify subdomain, not a relative path)

    OpenGraph preview

    1. Open opengraph.xyz

    2. Enter your page URL

    3. Confirm the preview shows the correct title, description, and image

    Twitter Card

    1. Open cards-dev.twitter.com/validator

    2. Enter your page URL

    3. Confirm the card shows correctly

    JSON-LD

    1. Open search.google.com/test/rich-results

    2. Enter your page URL

    3. Confirm no errors, and confirm the expected rich result appears

    Lighthouse

    1. Open Chrome DevTools (F12)

    2. Click the Lighthouse tab

    3. Click Analyze page load

    4. Confirm the SEO score is 100

    Lighthouse checks:

  • Title exists and is descriptive
  • Meta description exists
  • Links are crawlable
  • Page is indexable (no noindex)
  • robots.txt is valid
  • Canonical URL is valid
  • If any check fails, the Lighthouse report tells you why. Fix the issue in seo.dax or the content frontmatter, rebuild, and re-test.

    Search Console

    1. Open Google Search Console

    2. Check the "Pages" report — all URLs should eventually be "Indexed"

    3. Check the "Performance" report — after a week or two, queries should appear

    4. Check "Core Web Vitals" — the report is populated after real users visit

    The first month is slow. Google takes days to crawl, weeks to index, and weeks more to rank. Do not expect immediate results.


    Common SEO Mistakes

    Mistake 1: metadata.url is wrong.

    The most common SEO mistake. If metadata.url is https://your-site.netlify.app but the site is at https://yourdomain.com, canonical URLs, OpenGraph URLs, and JSON-LD URLs all point to the Netlify subdomain. Google indexes the Netlify subdomain, not your custom domain.

    Fix: update _data/metadata.yaml → url to the production domain. Rebuild.

    Mistake 2: Trailing slash in metadata.url.

    url: "https://yourdomain.com/"    # wrong
    

    url: "https://yourdomain.com" # correct

    The trailing slash produces https://yourdomain.com//about/ (double slash) in canonical URLs. Search engines may treat this as a separate URL.

    Mistake 3: Missing meta description.

    Every page should have a description in frontmatter. Without it, seo.dax falls back to metadata.description, which is generic. Generic descriptions appear in search results but do not attract clicks.

    Fix: write a 150–160 character description for every post and page.

    Mistake 4: Missing OpenGraph image.

    If og:image is empty or points to a broken URL, social media previews show no image. The click-through rate drops significantly.

    Fix: set image in _data/metadata.yaml for the default, and image per post for specific images.

    Mistake 5: Same image on every page.

    Using the default OpenGraph image for every post is better than no image, but page-specific images perform better. Each post's image should reflect its content.

    Mistake 6: Title too long or too short.

    Titles over 60 characters get truncated in search results. Titles under 30 characters do not carry enough information. Aim for 50–60 characters.

    Mistake 7: No _data/metadata.yaml url set.

    If url is empty, canonical URLs become relative (/about/), which search engines cannot resolve without context. The canonical should always be absolute.

    Mistake 8: Blocking crawlers accidentally.

    If you added Disallow: / to robots.txt for a staging site and forgot to remove it before going live, Google cannot crawl the site. Check robots.txt after every deployment.

    Mistake 9: JSON-LD is invalid.

    A missing comma or unmatched quote in the JSON-LD script invalidates the entire structured data. Search engines ignore it. Validate with the Rich Results tool.

    Mistake 10: Not submitting the sitemap.

    A sitemap that is not submitted to Search Console is still crawled eventually (search engines discover it via robots.txt), but submission accelerates discovery. Submit after every domain change.

    Mistake 11: Forgetting to verify the custom domain.

    If you verified your-site.netlify.app in Search Console, that verification does not cover yourdomain.com. Add the custom domain as a separate property and verify it.

    Mistake 12: Deleting old URLs without redirects.

    If you delete a page or change a URL, add a 301 redirect from the old URL to the new one. Otherwise, search engines see a 404 and remove the old URL from the index — losing any ranking it had.

    Dax Pro does not have built-in redirects. For redirects, use Netlify's redirects feature (create a _redirects file in public/) or configure them at the CDN level.


    What You Have Now

    After this chapter, you can:

  • ✅ Understand what Dax Pro generates automatically (sitemap, robots, RSS)
  • ✅ Configure canonical URLs correctly
  • ✅ Configure OpenGraph and Twitter Cards
  • ✅ Understand JSON-LD structured data
  • ✅ Submit your site to Google Search Console
  • ✅ Submit your site to Bing Webmaster Tools
  • ✅ Verify SEO with Lighthouse, Rich Results, and OpenGraph checkers
  • ✅ Fix the twelve most common SEO mistakes
  • ✅ Know when to add redirects and how
SEO for a static site is 90% configuration and 10% content. Dax Pro handles the technical side automatically. Your job is to configure metadata.yaml correctly, write clear titles and descriptions, and submit the sitemap. Everything else follows.

The next chapter is Analytics — how to add privacy-friendly analytics to a Dax Pro site, what tools are available, and how to install them without breaking the Lighthouse score.