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
- Enter any URL from your Zola site — the homepage, a blog post, or a section index page.
- 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.
- 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.
- 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.