Zola SEO audit

Zola is a fast Rust-based static site generator — single binary, TOML configuration, Tera templates, and static HTML output from Markdown content. Zola's speed is exceptional, but canonical tags, JSON-LD structured data, and robots.txt all require manual template setup. DeepSEOAnalysis audits your Zola site's rendered output: template meta tag coverage, canonical tag correctness (requires base_url in config.toml), structured data validation, sitemap and robots.txt configuration, Core Web Vitals from real CrUX data, and AI visibility scoring.

Run free Zola SEO audit →

What the audit checks on Zola sites

config.toml base_url and Tera template meta tag coverage
Zola's SEO configuration starts in config.toml. The base_url setting is required for correct absolute URL generation across the entire site — canonical tags, OG image URLs, sitemap entries, and internal link absolute URL helpers all depend on it. The audit validates the rendered static HTML: whether the <title> tag uses the page title (accessible via page.title in Tera templates) combined with the site title (config.title); whether meta description is set from page frontmatter description field (Zola does not auto-generate descriptions — a template must explicitly output a meta description tag referencing page.description or page.summary); whether OG title, OG description, og:image, og:url, og:type meta tags are present with absolute URLs; whether canonical tags are present using page.permalink (the absolute URL using base_url + page path); and whether pages marked with render = false in frontmatter are correctly excluded from the public/ build. Frontmatter audit: check that title, description, and date fields are consistently populated across content pages — Zola does not enforce required frontmatter fields.
URL structure and Zola permalink configuration
Zola generates URLs from the file system structure of the content/ directory. A file at content/blog/my-post.md generates /blog/my-post/ by default (with trailing slash). The slug can be overridden in frontmatter with slug = "custom-slug". The audit checks: whether page slugs are keyword-descriptive and hyphenated (filename = URL slug by default, so filename choice matters); whether the trailing slash behaviour is consistent with what the web server expects and how the canonical tag is formatted (mixing trailing slash and non-trailing slash canonical tags produces duplicate URL issues); whether section pages (content/blog/_index.md generating /blog/) are configured with appropriate title and description frontmatter for their meta tags; whether taxonomy pages (tag and category listing pages auto-generated by Zola) are configured correctly or excluded from indexing with noindex in their templates; and whether any paginated section pages (/blog/page/2/ etc.) carry rel="next"/rel="prev" pagination signals or are canonicalised.
JSON-LD structured data via Tera template customisation
Zola generates no JSON-LD by default. All structured data on Zola sites requires Tera template customisation. The audit validates: whether Article JSON-LD is present in the page's static HTML (present only if a template has been modified to include it); whether Article schema includes required properties — headline (from page.title), datePublished (from page.date formatted as ISO 8601 using the date Tera filter), dateModified (from page.updated if set, else page.date), author Person (from page.extra.author_name or config author config), image (from page.extra.og_image or a configured default — absent image is the most common Article schema eligibility failure); whether FAQPage JSON-LD is present on applicable pages (typically via shortcodes or a Tera block that page templates can populate); whether BreadcrumbList JSON-LD reflects the section hierarchy (the sections variable in Zola templates provides the breadcrumb chain); whether Organization and WebSite JSON-LD are in the base template; and whether all structured data is server-rendered in static HTML (guaranteed with Zola's build approach — no client-side JS rendering risk for template-generated schema).
Zola sitemap output, robots.txt, and static/ directory
Zola auto-generates sitemap.xml when base_url is set in config.toml — the sitemap is placed at public/sitemap.xml. The audit validates: whether sitemap.xml is accessible at the root URL; whether sitemap URLs are absolute (requires base_url — without it, URLs are relative and invalid); whether all public pages are included (draft pages with draft = true are excluded from zola build output; pages with render = false are also excluded); whether taxonomy pages (tag and category listing pages) are included in the sitemap and whether they should be (if they are thin content, filter them in a custom sitemap template); whether paginated section pages beyond page 1 are excluded from the sitemap; whether last-modified dates appear for pages with date or updated frontmatter; whether robots.txt is present at the site root (robots.txt must be placed in static/ — Zola copies the entire static/ directory to public/ at build; a robots.txt placed anywhere else will not be at /robots.txt); and whether robots.txt declares the sitemap URL using the absolute URL.
Core Web Vitals for Zola static sites
Zola generates fully static HTML with no JavaScript runtime. TTFB is excellent when served from a CDN — typically 20–60ms from edge locations. The fastest static site generators (Hugo, Zola, Eleventy) produce minimal per-page HTML without framework overhead. The main Core Web Vitals risks on Zola sites are from theme choices and third-party resources: (1) LCP — if the largest above-fold element is an image, verify it has fetchpriority="high" in the Tera template's img tag. Custom themes may not include this. (2) CLS — web fonts loaded from Google Fonts without font-display:swap can cause FOUT; fonts referenced in CSS without dimensions cause layout shift when they load. Prefer system fonts or self-hosted fonts with explicit @font-face font-display: swap. (3) INP — Zola sites typically have minimal JavaScript; INP risk comes from third-party widgets (comment systems, analytics) added to templates. Most Zola blogs use no JavaScript at all, producing excellent INP. Measure with real CrUX field data rather than Lighthouse alone — Zola's static output often means lab and field scores align closely.
AI visibility and GEO score for Zola static sites
Zola's fully static HTML output is ideal for AI crawlers — all content, headings, and template-rendered JSON-LD is in the initial server response with no JavaScript execution required. The five AI visibility signals for Zola: (1) AI crawler access in robots.txt — place robots.txt in static/robots.txt with explicit User-agent allowances for GPTBot, ClaudeBot, PerplexityBot, Google-Extended, and CCBot; Zola copies it to public/robots.txt at build. Without a robots.txt, all crawlers are allowed by default, but explicit configuration is better practice. (2) llms.txt — create static/llms.txt following the llms.txt specification; Zola copies it to public/llms.txt at build. Zola's technical audience makes it a strong llms.txt candidate — developer tools and technical documentation are frequently cited by AI systems. (3) FAQPage JSON-LD — add via Tera shortcodes or a template block that specific pages can populate. (4) Question-heading ratio — Zola Markdown content supports question-format H2s and H3s; the GEO score measures whether ≥20% of headings are phrased as questions. (5) Content chunkability — Zola's Markdown content with section headings creates well-chunked passages; verify sections are ≤400 words average for clean AI extraction.

How to audit your Zola site

  1. Enter any URL from your Zola site — the homepage, a blog post, or a section index page.
  2. DeepSEOAnalysis validates the static HTML output: Tera template meta tag and canonical tag coverage, JSON-LD structured data completeness and validity, robots.txt AI crawler access, sitemap presence and URL correctness, and Core Web Vitals from real CrUX field data.
  3. Review findings: missing canonical tags (typically base_url not configured), structured data property gaps, AI visibility score, and Core Web Vitals issues from real user sessions.
  4. Share the audit URL with your development team — no login required to view results.

Zola SEO frequently asked questions

Does Zola generate canonical tags automatically?
Zola does not generate canonical tags automatically — they must be added to the Tera template (typically templates/base.html or an equivalent head macro). Zola provides the current_url variable in templates, which contains the absolute URL of the current page when base_url is correctly configured in config.toml. To add canonical tags: in your base.html template, add <link rel="canonical" href="{{ current_url | safe }}"> inside the <head> block. The current_url variable uses the base_url from config.toml — if base_url is not set (a common oversight), current_url may return a relative path or empty string, producing broken canonical tags. Verify base_url is set to the exact production URL (base_url = "https://yourdomain.com") in config.toml. After adding canonical tags to the template, run zola build and inspect the generated public/ HTML files to confirm the canonical href is absolute and correct.
How does Zola handle sitemap generation?
Zola automatically generates a sitemap.xml at /sitemap.xml when base_url is configured in config.toml. The generated sitemap includes all pages, sections, and taxonomy pages that are not marked with render = false in frontmatter. Key sitemap behaviours: (1) Last modified dates — Zola includes <lastmod> in the sitemap if the page has an updated field in TOML frontmatter; otherwise it uses the date field. Without a date field, the page may appear in the sitemap without lastmod. (2) Taxonomy pages — tag and category index pages are included in the sitemap by default; if these are thin-content pages, add extra.noindex = true in taxonomy templates and filter them from sitemap output using a Tera template override. (3) Draft pages — pages with draft = true in frontmatter are excluded from the build output (and sitemap) unless the --drafts flag is passed to zola build. (4) Sitemap customisation — Zola allows overriding the default sitemap template by creating templates/sitemap.xml in your project; use this to add priority and changefreq fields or to filter specific sections. (5) The sitemap is only correct if base_url is set — without it, URLs in the sitemap are relative paths, which are invalid sitemap entries.
How do you add JSON-LD structured data to a Zola site?
Zola generates no JSON-LD by default — it must be added to Tera templates. The approach: (1) **Base template injection** — in templates/base.html, add a <script type="application/ld+json"> block inside the {% block head %}{% endblock %} section. Use Tera template variables: page.title (headline), page.date (ISO format via the Tera date filter: {{ page.date | date(format="%Y-%m-%dT%H:%M:%S") }}), page.permalink (absolute URL for @id and url — requires base_url set in config.toml), config.base_url + "/path/to/author-image.jpg" (for author image). (2) **Page-level override via extra** — define JSON-LD relevant fields in page TOML frontmatter under [extra]: author_name = "Jane Smith", og_image = "/images/post-cover.jpg". Reference these in the template via page.extra.author_name and page.extra.og_image. (3) **Shortcodes** — for FAQPage schema on specific pages, create a shortcode (templates/shortcodes/faqschema.html) that generates the JSON-LD and call it from Markdown content: {{ faqschema(questions=["Q1", "Q2"], answers=["A1", "A2"]) }}. All three approaches produce server-rendered JSON-LD in the static HTML output, which is the correct approach for Googlebot.
What are the most common SEO problems on Zola sites?
The most common Zola SEO issues: (1) **base_url not configured** — Zola\'s base_url is required for correct sitemap URLs, canonical tags (if using current_url), and absolute OG image URLs. Without it, sitemaps contain relative paths (invalid), canonical tags may be broken, and og:image may use relative URLs (invalid for social previews). Always set base_url = "https://yourdomain.com" in config.toml before any SEO work. (2) **No canonical tags in templates** — Zola has no built-in canonical output; templates must be customised. The default Zola starter templates typically don\'t include canonical tags. (3) **No JSON-LD structured data** — Zola generates no schema by default; all structured data requires Tera template work. (4) **No robots.txt** — Zola does not generate robots.txt; place robots.txt in the static/ directory (Zola copies the entire static/ directory to public/ at build). (5) **Taxonomy thin content** — Zola auto-generates tag and category listing pages. These contain minimal content (just post titles/excerpts) and are often thin. Consider noindex on taxonomy pages or enrich them with hand-written introductory content. (6) **Draft pages in production** — if deploying with zola build (without --drafts), draft pages are correctly excluded. If using zola serve or a misconfigured deployment script with --drafts, draft content can be accidentally published.