Hexo SEO audit

Hexo is a fast Node.js static site generator for blogs — Markdown content, EJS/Pug/Nunjucks theme templates, and fully static HTML output. Hexo's static generation is excellent for crawlability, but canonical tags, JSON-LD structured data, and sitemap generation all require manual theme configuration or plugins. DeepSEOAnalysis audits your Hexo site's rendered HTML: meta tag coverage from theme templates, front matter field completeness, structured data server-rendering, Core Web Vitals from real CrUX data, and AI visibility scoring.

Run free Hexo SEO audit →

What the audit checks on Hexo sites

Hexo theme meta tag coverage and front matter fields
Hexo's meta tag output depends entirely on the theme's head template (head.ejs, head.pug, or equivalent). The audit validates what is actually rendered in the static HTML: whether the <title> tag uses the post title (page.title variable) or falls back to the site title (config.title); whether meta description is populated from page.excerpt or a front matter description field (many Hexo themes output empty description tags if the front matter field is absent); whether OG title, OG description, and OG image are configured with absolute URLs (OG image must be absolute — relative paths are invalid in og:image); whether canonical tags are present and correctly computed using config.url + url_for(page.path); and whether per-post custom canonical URLs are honoured for cross-posted content. Front matter audit: the audit checks whether standard Hexo front matter fields (title, date, updated) are populated, and whether custom fields your theme references (author, og_image, description) are consistently populated or have sensible fallbacks.
URL structure and permalink configuration
Hexo's URL structure is configured in _config.yml via the permalink option. The default is :year/:month/:day/:title/ which produces date-based paths (/2021/03/15/my-post-title/) — problematic for evergreen content because the date appears in the URL, making content look stale in SERPs. For evergreen technical blogs, :title/ or :category/:title/ produces cleaner, date-free URLs. The audit checks: whether the permalink structure is keyword-descriptive and date-free for evergreen content; whether post slugs (derived from the post filename or the slug front matter field) are hyphenated and lowercase; whether tag and category archive URLs (/tags/[tag]/, /categories/[category]/) are correctly configured; whether hexo-abbrlink or similar permalink plugins are used for fixed short URLs (short but opaque — the tradeoff is brevity vs keyword signal); and whether 301 redirects exist for any previously published posts whose URLs have changed from permalink structure updates.
JSON-LD structured data via theme templates or plugins
Hexo's static HTML output means JSON-LD added to theme templates is server-rendered in every generated page — which is the correct approach. The audit validates: whether Article JSON-LD is present on blog post pages (headline from page.title with 110-character limit, datePublished from page.date in ISO 8601 format, dateModified from page.updated or page.date, author Person with name from config.author or page.author front matter field, image from page.og_image or a configured default — absent or empty image is a common validation error); whether FAQPage JSON-LD is present on pages structured as FAQ content; whether BreadcrumbList JSON-LD reflects the site hierarchy (blog root → category if applicable → post); whether Organization and WebSite JSON-LD are in the root layout; and whether JSON-LD is server-rendered in the static HTML output (it should be, since Hexo generates static files at build time). Common Hexo structured data errors: relative image URLs in image property (must be absolute), missing image entirely (the most common rich result eligibility failure), and page.date outputting a Date object rather than an ISO string (use page.date.toISOString() in EJS templates).
hexo-generator-sitemap and robots.txt
Hexo does not generate a sitemap by default — the hexo-generator-sitemap plugin must be installed (npm install hexo-generator-sitemap) and configured in _config.yml with a sitemap path and options. The audit validates: whether sitemap.xml is accessible at the root URL; whether all published posts and pages are included (draft posts with draft: true should be excluded); whether the sitemap includes lastmod dates (hexo-generator-sitemap uses the post updated date or date field); whether tag archive pages and category archive pages are excluded from the sitemap (they are typically thin content); whether pagination pages (/page/2/ etc.) are excluded from the sitemap; whether the sitemap is declared in robots.txt; and whether robots.txt exists in the public root (place it in source/robots.txt so Hexo copies it to public/robots.txt at build time). The robots.txt must explicitly allow AI crawlers (GPTBot, ClaudeBot, PerplexityBot) — the default absence of robots.txt means all crawlers are allowed, but explicitly declaring AI crawler access is better practice for GEO visibility.
Core Web Vitals for Hexo static sites
Hexo generates fully static HTML files served from a CDN or web server, which provides excellent TTFB performance — static files typically return first bytes in 20–100ms from CDN edge locations. The main Core Web Vitals risks on Hexo sites are theme-dependent: (1) LCP — if the largest above-fold element is a featured/hero image, ensure it has fetchpriority="high" in the theme's img tag template; many default Hexo themes don't include fetchpriority. (2) CLS — fonts loaded from Google Fonts or other external CDN can cause FOUT (Flash of Unstyled Text) if font-display: swap is not configured; image dimensions not specified in theme templates cause layout shift when images load. (3) INP — most Hexo themes include minimal JavaScript; the main INP risks come from third-party widgets (Disqus comments, social sharing buttons, analytics tags), not from Hexo's own JS. Measure with real CrUX field data — not just Lighthouse lab scores — to see actual user experience on real devices and connection speeds. Hexo's static output means lab scores and field data are typically close, unlike JavaScript-heavy frameworks where there's often a significant gap.
AI visibility and GEO score for Hexo sites
Hexo's static HTML output is excellent for AI visibility: all page content, headings, and theme-rendered JSON-LD is in the initial server response, making it immediately accessible to AI crawlers without JavaScript execution. The five AI visibility signals for Hexo: (1) AI crawler access in robots.txt — add explicit User-agent allowances for GPTBot, ClaudeBot, PerplexityBot, Google-Extended, and CCBot in source/robots.txt (Hexo copies this to public/robots.txt at build); without a robots.txt, crawlers are allowed by default, but explicit configuration is better practice. (2) llms.txt — create source/llms.txt following the llms.txt spec; Hexo will copy it to public/llms.txt. Alternatively, add an EJS/Pug template in source/_posts or create a dedicated page template that generates /llms.txt dynamically. (3) FAQPage JSON-LD — add to the head template for FAQ-structured posts via theme template or the hexo-structured-data plugin. (4) Question-heading ratio — Hexo blog content can use question-format H2s and H3s in Markdown; the GEO score measures what percentage of headings are phrased as questions (target ≥20%). (5) Content chunkability — Hexo's Markdown-based content with section headings naturally creates well-chunked content; verify that post content has section headings breaking up prose every 300–400 words.

How to audit your Hexo blog

  1. Enter any URL from your Hexo site — homepage, a blog post, or a category archive page.
  2. DeepSEOAnalysis validates the static HTML output: theme-rendered meta tags and canonical tags, JSON-LD structured data completeness, robots.txt AI crawler access, and Core Web Vitals from real CrUX field data.
  3. Review findings: structured data property errors, missing canonical tags, AI visibility score, and any Core Web Vitals issues from real user sessions.
  4. Share the audit URL with your development team — no login required to view results.

Hexo SEO frequently asked questions

Does Hexo have good SEO out of the box?
Hexo generates static HTML at build time, which is a strong SEO foundation — all content is in the initial HTML response without JavaScript rendering requirements. However, Hexo\'s default theme (hexo-theme-landscape) has several SEO gaps: it does not output canonical tags, does not generate JSON-LD structured data, and relies on generic Open Graph tags. The SEO quality of a Hexo site depends heavily on the theme and plugins installed. Key Hexo SEO configuration requirements: (1) hexo-generator-sitemap plugin — generates sitemap.xml automatically from all posts and pages; must be installed separately, it is not bundled with Hexo. (2) hexo-generator-feed plugin — generates RSS feed. (3) Theme meta tag templates — the _partial/head.ejs (or equivalent for your theme\'s template engine) controls what meta tags appear in <head>. Many themes include basic title and description tags but miss canonical tags and OG tags. (4) Front matter fields — title, description (excerpt), date, and tags are standard Hexo front matter. Add custom fields (canonical_url, og_image) if your theme\'s head template references them. (5) robots.txt — place a robots.txt in the source/ directory; Hexo copies it to the public/ root at build time.
How do you add canonical tags to a Hexo site?
Hexo does not generate canonical tags by default — they must be added to the theme\'s head template. The approach depends on your template engine: (1) EJS templates — in themes/[theme-name]/layout/_partial/head.ejs, add: <link rel="canonical" href="<%- config.url %><%- url_for(page.path) %>">. The url_for() helper generates the correct relative-to-root path; prepend config.url for the absolute URL required in canonical tags. (2) Pug/Jade templates — link(rel="canonical", href=config.url + url_for(page.path)). (3) Nunjucks templates — <link rel="canonical" href="{{ config.url }}{{ page.path }}">. For custom canonical URLs on specific posts (e.g., cross-posted content), add a canonical_url field to the post\'s front matter and reference it in the template: <%- page.canonical_url || (config.url + url_for(page.path)) %>. After adding canonical tags to the theme template, run hexo clean && hexo generate and verify the output in public/[post-slug]/index.html.
How do you add structured data JSON-LD to Hexo?
Hexo\'s static generation means JSON-LD must be added to theme templates — it will be server-rendered in every page\'s static HTML at build time. Approaches: (1) **Theme template injection** — in your theme\'s head.ejs or layout template, add a <script type="application/ld+json"> block using EJS/Pug/Nunjucks to populate Article schema properties from page variables: headline from page.title, datePublished from page.date.toISOString(), dateModified from page.updated?.toISOString() || page.date.toISOString(), author.name from config.author (or page.author if a per-post author field is defined), image from page.og_image || config.default_og_image. (2) **Hexo plugin** — the hexo-structured-data plugin (community package) auto-generates Article JSON-LD for posts. Verify the generated output contains all required properties (Article requires: @type, headline, datePublished, image — this is a common omission in community plugins). (3) **Front matter injection** — add a json_ld field in specific post front matter containing the raw JSON string; render it in the template as <%- page.json_ld %>. This is flexible but manual.
What are the most common SEO problems on Hexo sites?
The most common Hexo SEO issues: (1) **No canonical tags** — the default Hexo setup and most themes do not output canonical tags. Every page has potential canonical gaps from pagination, tag archives, and category archives. (2) **Tag and category archive thin content** — Hexo generates /tags/[tag]/ and /categories/[category]/ index pages by default. These pages contain only post excerpts or titles and typically qualify as thin content; they should be evaluated for noindex or significantly improved. (3) **No JSON-LD structured data** — Article schema is absent from most default themes and must be added manually or via plugin. (4) **Pagination canonical confusion** — hexo-generator-archive creates paginated archive pages at /page/2/, /page/3/ etc. Without canonical tags pointing back to /page/1/ or the root archive, these pages may be indexed as duplicates of the root. (5) **Missing OG image** — many Hexo themes don\'t configure a default OG image, producing og:image tags with empty values or missing entirely. (6) **robots.txt absent** — Hexo does not generate robots.txt by default. Without one, no sitemap declaration is present for crawlers.