Hexo SEO
How to do SEO on a Hexo site — the Node.js static site generator. Hexo outputs pure HTML so content is crawlable on the first fetch, but sitemaps, robots.txt, meta descriptions, canonicals, structured data, and stable permalinks all depend on plugins and config.
Hexo is a Node.js static site generator: hexo generate compiles Markdown into pure static HTML, so Googlebot reads your full content on the first fetch with no JavaScript rendering queue. That's the crawlability floor — but it's not finished SEO. Most default themes ship no sitemap, no robots.txt, no per-post meta description, no canonical, and no structured data; you add those with _config.yml settings, front matter fields, theme edits, and plugins (hexo-generator-sitemap, hexo-generator-robotstxt, hexo-generator-feed, hexo-abbrlink). The big traps are a wrong url: in _config.yml, the date-based default permalink that breaks links on rename, and auto-generated category/tag archives that create thin duplicate content. For Baidu-facing sites, the static output removes a real crawling obstacle — though that's not a guarantee of Baidu indexing or ranking.
TL;DR — Hexo builds your blog into plain HTML files ahead of time, so Google sees your content the moment it fetches a page — no waiting on JavaScript. That’s the easy part. The catch: Hexo doesn’t add a sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., a
robots.txt, meta descriptions, or canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content. on its own. You turn those on with a few plugins and config settings.
What Hexo is
Hexo is a free blogging framework built on Node.js. You write posts in Markdown,
run hexo generate, and Hexo turns everything into finished HTML files. You upload
those files to a host (GitHub Pages, Netlify, Cloudflare Pages, and so on). When
Google or a reader requests a page, they get the complete HTML right away — there’s
nothing left for the browser to build. Evidence for this claim Hexo generates static site files from source content. Scope: Hexo static generation. Confidence: high · Verified: Hexo documentation
That’s great for SEO: your text and links are in the page from the first byte, so Google doesn’t have to run any JavaScript to find your content. Hexo sits in the same family as Hugo and Jekyll — all of them pre-build everything (see Static Site GeneratorsA build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers.).
What Hexo does not do for you
Here’s where beginners get caught: a fresh Hexo site with a default theme is missing most basic SEO pieces. You usually have to add:
- An XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. — install the
hexo-generator-sitemapplugin. Evidence for this claim The official Hexo sitemap generator creates sitemap.xml output. Scope: hexo-generator-sitemap plugin. Confidence: high · Verified: Hexo sitemap generator - A
robots.txt— installhexo-generator-robotstxt(or drop a file in your source folder). - Meta descriptionsThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through. — add a
description:to each post, and most themes need a small template edit to actually print it. - Canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content. — theme-dependent; the popular NexT theme can do it once you set things up.
The two settings that matter most before you launch
In your _config.yml file:
url:must be set to your real live address withhttps://(for examplehttps://yourdomain.com). Get this wrong and your sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., canonical, and feed links all point to the wrong place.permalink:controls your URL pattern. The default puts the date in every URL. Many people prefer a cleaner:title/. Whatever you pick, don’t change a post’s URL later without a redirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. — it breaks links and loses ranking signals.
The thing most people get wrong
“It’s static HTML, so SEO is automatic.” No. Static HTML means Google can crawl your content easily — that’s a head start, not a finish line. You still need the sitemap, the meta descriptionsThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., the canonical tags, and good content. The static part just means you won’t have the JavaScript indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. problems that single-page apps have.
Want the full version — every plugin, the NexT theme fixes, the category/tag duplicate-content trap, structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding., and Baidu targeting? Switch to the Advanced tab.
TL;DR — Hexo (
hexo generate) emits pure static HTML, so your content is in the first byte of the response — no Web Rendering ServiceTurning HTML, CSS, and JavaScript into the final visual page and DOM., no Wave 2 delay. That’s the crawlabilityCrawlability is how well search engine crawlers can discover, access, and fetch a site's pages. A crawlability issue is any technical condition — blocked access, broken links, server failures, or bloated URL inventory — that stops pages from reaching the index. floor, not finished SEO. Default themes ship no sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., no robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere., no per-post meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., no canonical, and no structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding.; you add them via_config.yml, front matter, theme template edits, and plugins (hexo-generator-sitemap,hexo-generator-robotstxt,hexo-generator-feed,hexo-abbrlink,hexo-indexnow). The three traps that actually bite: a wrongurl:in_config.ymlbreaks canonicals/sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing./feed; the date-based default permalink ties URLs to filenames so a rename breaks links; and auto-generated category/tag archives create thin duplicate contentThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling.. For Baidu-facing sites the static output is a real advantage.
Hexo’s static output is the crawling advantage
hexo generate runs your Markdown and theme templates through a build step and writes
a folder of finished HTML, CSS, and assets. The SEO-relevant fact is when the HTML
exists: at build time, once, for everyone — not per request, and not in the browser. Evidence for this claim The Hexo generate command builds static files into the configured public directory. Scope: Hexo generate command. Confidence: high · Verified: Hexo: Commands
Google describes a two-phase process for JavaScript pages: Wave 1 fetches the raw HTML and indexes static content immediately; Wave 2 is a deferred headless-Chromium renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. queue that can take seconds to days. Hexo output skips Wave 2 entirely — every page is raw HTML on the first fetch. Google’s own guidance is blunt that this is the recommended path: dynamic rendering was “a workaround and not a long-term solution… use server-side rendering, static rendering, or hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. as a solution,” and Hexo produces static rendering, one of the three explicitly recommended approaches.
Two more wins fall out of this:
- Crawlable links by default. Hexo templates emit plain
<a href>anchors in static HTML, so they satisfy Google’s requirement that links be real, crawlable URLs — no JavaScript-generated navigation to design around. - Cheap to crawl. Static files served from a CDN have effectively zero server-processing cost per request, so GooglebotGooglebot is Google's web crawler — the software that fetches pages so Google can index and rank them. It comes in two variants, Googlebot Smartphone (primary, under mobile-first indexing) and Googlebot Desktop, and runs an evergreen Chromium renderer. can crawl at its allowed rate without tripping crawl-rate throttling. As Gary Illyes put it, “if you are making expensive database calls, that’s going to cost the server a lot” — Hexo makes none.
The caveat: zero render-blockingRender-blocking resources are CSS and synchronous JavaScript files a browser must download and process before it can paint any visible content. They sit on the critical rendering path and delay First Contentful Paint and Largest Contentful Paint. for crawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. is not the same as zero render-blocking for users. Theme JS/CSS still affects Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. (more below).
Configure _config.yml first — url: is the big one
Set these global keys before your first deploy:
url: https://yourdomain.com # must match your live domain, with https://
permalink: :title/ # or :year/:month/:day/:title/ (the default)
title: Site Title
description: Global meta description fallback
author: Your Name
language: en
meta_generator: false # removes the <meta name="generator" content="Hexo"> tagurl:is the single most consequential setting. It’s the site’s configured base URL, which themes and generators can use for canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content., feeds, sitemaps, and paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does.. A wrong value can propagate into those outputs. Evidence for this claim Hexo's url configuration supplies the website URL used by themes and generators. Scope: Exact downstream fields depend on the installed theme and plugins. Confidence: high · Verified: Hexo: Configurationpermalink:— the default:year/:month/:day/:title/produces date-based URLs that look stale over time and tie the slug to the filename. Cleaner options are/:title/or/:category/:title/.meta_generator: falsestrips Hexo’s generator fingerprint from<head>.- Deploying to a subdirectory?
url:alone isn’t enough — setroot:to the subdirectory path too (e.g.root: /blog/). Hexo’surl_forhelper builds root-relative links, whilefull_url_forprepends the fullurl:value; getroot:wrong on a subdirectory deploy and internal linksAn internal link is a hyperlink from one page on a website to another page on the same website. Internal links help search engines discover your pages and pass ranking signals (PageRank and anchor-text context) between them., feeds, and sitemap entries end up pointing at the domain root instead of the actual path. - Config precedence: the site’s
_config.ymlsets the baseurl/root/permalinkvalues; a theme’s own config (its bundled_config.yml, or a_config.<theme>.ymlat the project root) layers on top for display and template settings, but doesn’t override the site-level URL structureURL structure is how the parts of a web address — scheme, domain, path, query string, and fragment — are organized and formatted. It mostly affects crawling, usability, and how engines understand a page, not rankings directly. — a theme can’t fix a wrongurl:. - Testing in safe mode?
hexo server --safe(orhexo --safe) disables every plugin and script, so the output you’re viewing is missing your sitemap, robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere., and any SEO plugin’s tags. Don’t use a safe-mode preview to check SEO output — run a normalhexo generatefirst.
Front matter SEO controls (and what’s missing)
Native Hexo front matter you can rely on:
---
title: "Article Title for the <title> tag"
date: 2024-01-15
updated: 2024-06-01
tags: [tag1, tag2]
categories: [Category]
permalink: /custom-url/ # overrides the global pattern for this post
published: true
sitemap: false # exclude this post from sitemap.xml
---What is not in native front matter and needs theme support or a template edit:
description(the meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through.) — most themes don’t print it without a patch.keywords(per-post keyword meta) — and largely pointless anyway; Google has ignored<meta name="keywords">since 2009. Treatkeywordsas an organizational aid, not a ranking lever.canonical(override the canonical URL) — theme-dependent.
Keep the updated: field current when you revise a post — sitemap freshness depends
on it (next section).
Essential plugins
Sitemap — hexo-generator-sitemap (official):
npm install hexo-generator-sitemap --savesitemap:
path:
- sitemap.xml
tags: true
categories: trueIt reads lastmod from each post’s updated field (falling back to date) — which
matters because Bing warns that lastmod “should reflect the true last modification
time of the page content, not the sitemap file itself.” After hexo generate, submit
the resulting sitemap.xml in Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. and Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility.. And
heed Bing’s other warning: “Do not submit a static sitemap and forget it. New pages
won’t get picked up” — for Hexo that means re-deploying and re-submitting (or using
IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it.) after every new post.
The sitemap can be well-formed while a wrong `_config.yml` `url:` turns its locations into relative or incorrect URLs. Test the deployed artifact after a production generate.
Check the sitemap with my free XML Sitemap Validator Free
- Generate and deploy with the production base URL.
- Validate locations, lastmod values, duplicates, and XML syntax in the public sitemap.
- Fix `_config.yml`, front matter, or the generator source, then regenerate and retest.
The validator reports that the loc element is not an absolute URL and says sitemap URLs must be fully qualified rather than relative paths.
robots.txt — hexo-generator-robotstxt:
npm install hexo-generator-robotstxt --saverobotstxt:
useragent: "*"
allow:
- /
disallow:
- /private/
sitemap: https://yourdomain.com/sitemap.xmlWithout it, Hexo produces no robots.txt at all — no sitemap pointer for crawlers.
RSS — hexo-generator-feed: relevant for aggregators and Google News eligibility;
John Mueller includes an RSS feed on his own static site.
IndexNow — hexo-indexnow: Bing recommends pairing sitemaps with IndexNow for
real-time, URL-level submission. Drop the generated key file into source/ so it
deploys as yourdomain.com/<key>.txt. Note this is for Bing, Yandex, and others —
not Google, which doesn’t use IndexNow for general pages.
Permalink stability — the abbrlink fix
The default permalink has two SEO problems: renaming the Markdown file changes the URL
(because the slug comes from the filename), and non-Latin titles (Chinese, emoji)
produce garbled URLs. hexo-abbrlink decouples the URL from the filename by writing a
stable hash back into front matter:
npm install hexo-abbrlink --savepermalink: posts/:abbrlink/
abbrlink:
alg: crc32 # crc16 or crc32
rep: hex # dec or hexYou get something like /posts/3a9c2b1d/ that survives file renames, category
changes, and date edits. The underlying rule stands either way: once a URL is
published, don’t change it without a 301 redirectA 301 redirect is the HTTP status code for a permanent move: it tells browsers and search engines a URL has moved for good, and it's the strongest signal for consolidating a page's ranking signals onto the new URL. Google says permanent redirects don't cause a loss in PageRank. — a rename without one destroys
link equity and any accumulated ranking signals.
Two more permalink pitfalls worth knowing before you pick a pattern:
- Don’t use the
:idtoken. Hexo documents post IDs as not persistent across a database cache reset — if your permalink pattern includes:id, a cache rebuild can silently change every post’s URL. Stick to:title,:abbrlink, or another stable token. trailing_indexandtrailing_htmlare separate controls, not one setting. Hexo’spretty_urlsconfig toggles them independently — one governs whether a trailingindex.htmlis stripped from generated links, the other whether a trailing slash is added. If these don’t match how your host actually resolves URLs (some hosts redirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't./postto/post/, others don’t), you can end up with internal links, canonicals, and sitemap entries disagreeing with the URL the server actually serves.
NexT theme SEO configuration
NexT is the most-used Hexo theme, configured in _config.next.yml:
canonical: true # builds canonical from url: + page path
webmaster_tools:
google: VERIFICATION_STRING
bing: VERIFICATION_STRING
baidu: VERIFICATION_STRING
open_graph:
enable: true
twitter_card: summary_large_imageThe NexT meta-description gap: NexT does not automatically inject a per-post
<meta name="description"> from the front matter description:. You patch the theme’s
head template to fall back from page.description to the site description. This is the
single most common NexT SEO miss. (NexT does support canonical: true and built-in
Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. / Twitter Cards, so those at least work once enabled.)
For non-NexT themes, you usually create or edit a head partial to emit og:title,
og:description, og:image, og:url, and twitter:card — support varies widely by
theme.
Who owns each tag when a theme and a plugin both emit it. A theme’s built-in
Open Graph/canonical support and an all-in-one plugin like hexo-seo (which
generates its own breadcrumb, website, and article schemaArticle schema (Article, NewsArticle, or BlogPosting) is structured data marking up a written piece's headline, author, and dates — Google labels it the \"Article rich result,\" but it's a better-displayed existing result, not a distinct new card, and it isn't required for Top Stories or Discover eligibility.) can both try to write the
same tag. Turning both on produces duplicate or conflicting <meta> tags, canonicals,
or JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. blocks in the same <head>. Pick one layer as the owner for each tag
category — theme or plugin, not both — and disable the corresponding feature on the
other before you ship.
Category and tag pages: the duplicate-content trap
Hexo auto-generates an archive page for every category and every tag, each filled with post excerpts that also appear on the posts themselves. At scale that’s hundreds of thin pages competing for the same queries and diluting crawl attention. Your options:
sitemap: falseper archive (impractical at scale).- Theme-level
noindexon the category/tag archive templates. - Keep them indexed only if a category is a genuine, curated topic hub with real value.
- Self-referencing canonical on each paginated archive page (page 2 canonicalizes to itself, not page 1).
One caveat on option 2: long-term noindex eventually makes Google stop following the
links on that page, so noindexing tag pages can reduce crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. of posts that are only
linked from those tags. Make sure such posts are reachable some other way.
Your route inventory is bigger than source/. Category, tag, archive, and
pagination pages don’t come from Markdown files — Hexo’s generator API is what
actually creates them, and themes or plugins can register their own generators too.
That means the crawlable URL surface can silently expand beyond what you’d expect
from browsing your source/ folder. After installing or updating a theme or plugin,
run hexo generate and diff the route list in public/ rather than assuming you
know every URL Hexo is producing.
Structured data / JSON-LD
Hexo injects no structured data by default. Either add a BlogPosting JSON-LD block to
your theme’s post template (headline, datePublished, dateModified, author,
publisher, url) or use an all-in-one plugin like hexo-seo that generates
breadcrumb, website, and article schema for you.
Core Web Vitals
Static output is fast, but themes can undo that. NexT and many themes bundle large
JS/CSS and icon-font libraries (Font Awesome is a frequent LCPLargest Contentful Paint — render time of the largest visible image or text block, relative to when the page started loading. ≤2.5 s (at the 75th percentile) is good./render-blocking
culprit). Audit with LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal., then reach for hexo-all-minifier (HTML/CSS/JS
compressionCompression (HTTP content encoding) shrinks text-based responses — HTML, CSS, JS, JSON, SVG, XML sitemaps — before they're sent over the network, using an algorithm like Gzip, Brotli, or Zstd, so the browser or crawler downloads fewer bytes. It's not a ranking factor, but it speeds up page loads and helps pages stay under crawler fetch limits. at build time), hexo-lazyload-image, and defer/async on third-party
scripts like analytics and ads.
Targeting Baidu (Chinese-audience sites)
Baidu’s crawler handles JavaScript poorly, so Hexo’s static HTML removes one obstacle
to Baidu discovery. Add baidu_site_verification in NexT, generate a Baidu-format
sitemap with hexo-generator-baidu-sitemap, and push URLs actively with
hexo-submit-urls-to-search-engine. One hosting note: GitHub Pages is blocked in
mainland China — use Gitee Pages, Cloudflare, or a Chinese CDN for Baidu traffic.
Treat that as a crawlabilityCrawlability is how well search engine crawlers can discover, access, and fetch a site's pages. A crawlability issue is any technical condition — blocked access, broken links, server failures, or bloated URL inventory — that stops pages from reaching the index. advantage, not a guarantee. Static HTML doesn’t by itself prove Baidu is discovering, indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., or ranking your pages — confirm actual crawl activity and indexing status directly in Baidu Ziyuan (Baidu’s webmaster tools) rather than assuming static output alone secures visibility.
Deploying to GitHub Pages — the SEO gotchas
- Set
url:to your live address (custom domain withhttps://) before the first deploy. - Put a
CNAMEfile insource/for custom domains so it isn’t reset on everyhexo deploy. - Enforce HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.' in repo Settings → Pages after DNS propagates.
- Prefer a GitHub Actions workflow over
hexo-deployer-gitto avoid CNAME-reset issues.
Hexo vs. Hugo vs. Jekyll vs. Astro, for SEO
All four ship pure static HTML, so the indexability floor is identical — there’s no framework-level SEO disadvantage in Hexo. The differences are operational: Hugo (Go) builds far faster at large scale and has a built-in sitemap; Jekyll is the GitHub Pages default; Astro ships zero JS by default via islands. Hexo’s edge is a rich npm plugin ecosystem and a large Chinese-language community. Content quality, not the generator, decides rankings — as Mueller said of switching generators, “Will your site’s SEO suddenly explode? No. Also No.”
For the cluster overview and the other generators, see Static Site GeneratorsA build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers.; for the broader rendering picture, see JavaScript SEOMaking sure search engines can crawl, render, and index content that depends on JavaScript..
AI summary
A condensed take on the Advanced version:
- Hexo is a Node.js static site generatorA build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers..
hexo generateoutputs pure static HTML, so content is in the first byte of the response — no Web Rendering ServiceTurning HTML, CSS, and JavaScript into the final visual page and DOM., no Wave 2 renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM.-queue delay. Crawlable<a href>links and cheap-to-crawl CDN files come free. - Static HTML is the crawlabilityCrawlability is how well search engine crawlers can discover, access, and fetch a site's pages. A crawlability issue is any technical condition — blocked access, broken links, server failures, or bloated URL inventory — that stops pages from reaching the index. floor, not finished SEO. Default themes ship no sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., no robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere., no per-post meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., no canonical, and no structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding..
- Configure
_config.ymlfirst.url:is the most consequential setting — it feeds canonicals, sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., RSSAn RSS or Atom feed is an XML file listing a site's most recently published or updated URLs. Search engines accept it as a sitemap-style discovery signal for fresh content — not a replacement for a full XML sitemap., and paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does.; a wrong value breaks all of them. Subdirectory deploys also needroot:set. Pick a cleanpermalink:(avoid the:idtokenA token is the smallest unit of text (or image/audio/video) an LLM processes — roughly 4 characters, or about ¾ of an English word. A context window is the maximum number of tokens (input plus output) a model can hold at once, like its short-term memory. — it isn’t persistent across a cache reset) and setmeta_generator: false. A theme’s own config can’t override the site-levelurl/root/permalink, and a safe-mode preview (--safe) disables every plugin and script, so don’t check SEO output there. - Plugins do the heavy lifting:
hexo-generator-sitemap(readslastmodfrom theupdatedfield),hexo-generator-robotstxt,hexo-generator-feed,hexo-indexnow(Bing/Yandex, not Google),hexo-abbrlinkfor stable permalinks. - NexT theme: supports canonical + Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears., but does not auto-print a per-post meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through. — a template patch is the most common fix. If a theme and an SEO plugin can both emit the same tags, enable only one per tag category to avoid duplicates.
- Three traps: wrong
url:; the date-based default permalink that breaks links on rename (never change a URL without a 301); and auto-generated category/tag archives that create thin duplicate contentThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling. (noindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. or canonicalize). Those archive/tag/ paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. routes come from Hexo’s generator API, notsource/files — a theme/plugin update can silently expand the indexable URL surface, so diffpublic/after changes. - Baidu: static output removes a real obstacle (Baidu’s crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. handles JS poorly), but it’s a crawlabilityCrawlability is how well search engine crawlers can discover, access, and fetch a site's pages. A crawlability issue is any technical condition — blocked access, broken links, server failures, or bloated URL inventory — that stops pages from reaching the index. advantage, not a guarantee of indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. or ranking — confirm in Baidu Ziyuan. GitHub Pages is blocked in China — use Gitee/Cloudflare/a Chinese CDN.
- Vs. Hugo/Jekyll/Astro: same indexability floor; Hexo’s edge is the npm plugin ecosystem and Chinese community. Content quality decides rankings, not the generator.
Official documentation
Primary-source documentation — from Hexo, the search engines, and the key plugins.
Hexo
- Hexo documentation — the framework overview.
- Configuration —
url,permalink,meta_generator, and the rest of_config.yml. - Permalinks — URL pattern variables and tradeoffs.
- Front matter — the per-post fields Hexo supports natively.
- GitHub Pages deployment — the official deploy guide.
Plugins
- hexo-generator-sitemap — the official sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. plugin.
- hexo-abbrlink — stable hash-based permalinks.
- NexT theme SEO settings — canonical, webmaster verification, Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears..
Search engines — renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., links, sitemapsA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.
- JavaScript SEO basics — the crawl → render → indexStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. phases a static build lets you skip for content.
- Dynamic rendering (deprecated) — Google recommending static renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. instead.
- Make your links crawlable — the
<a href>requirement Hexo satisfies by default. - SEO Guide for Web Developers — titles, descriptions, canonicals, sitemaps, structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding..
- Bing — Keeping Content Discoverable with Sitemaps — XML preference,
lastmodaccuracy, and IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it..
Quotes from the source
On-the-record statements from Google, Bing, and John Mueller that bear directly on a Hexo (static) site.
Google — static renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. is the recommended path
- “Dynamic renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. was a workaround and not a long-term solution for problems with JavaScript-generated content in search engines… Instead, we recommend that you use server-side rendering, static rendering, or hydrationActivating server-rendered HTML in the browser by attaching JavaScript handlers. as a solution.” — Hexo produces static rendering. Source
- “Server-side or pre-rendering is still a great idea because it makes your website faster for users and crawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index., and not all bots can run JavaScript.” Source
Bing — sitemapsA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. and freshness
- “XML remains the preferred format for sitemapsA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.” — because it supports structured metadata like
lastmodfor freshness assessment. Source - On
lastmod: it “should reflect the true last modification time of the page content, not the sitemap file itself.” — the Hexo gotcha that theupdatedfield must be kept current. Source - “By combining sitemaps for comprehensive site coverage with IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it. for fast, URL-level submission, you provide the strongest foundation for keeping your content fresh, discoverable, and visible.” Source
Gary Illyes, Google — static sites are cheap to crawl
- “If you are making expensive database calls, that’s going to cost the server a lot.” — static HTML from a CDN makes none. Coverage
John Mueller — switching generators isn’t itself an SEO win
- “Will this change how your site appears in all search engines? Will your site’s SEO suddenly explode? No. Also No.” — content quality, not the generator choice, drives rankings. Source
Hexo SEO checklist
A pass to confirm a Hexo site is search-friendly — most of these are off by default:
-
url:in_config.ymlis your live domain withhttps://(not a placeholder, nothttp://). Deploying to a subdirectory?root:is set too. - A permalink pattern is chosen and won’t churn — ideally
:title/orhexo-abbrlinkfor stable hashes. The:idtokenA token is the smallest unit of text (or image/audio/video) an LLM processes — roughly 4 characters, or about ¾ of an English word. A context window is the maximum number of tokens (input plus output) a model can hold at once, like its short-term memory. is not used (it isn’t persistent across a database cache reset). - If both a theme and an SEO plugin can emit canonical/OG/JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. tags, exactly one of them is enabled for each tag category — not both.
-
meta_generator: falseset to drop the Hexo fingerprint (optional but tidy). -
hexo-generator-sitemapinstalled;sitemap.xmlgenerates and is submitted in Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. and Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility.. -
updated:front matter is kept current so sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.lastmodis accurate. -
hexo-generator-robotstxtinstalled (or a manualrobots.txtinsource/) with the sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. pointer. - Each post has a
description:, and the theme actually prints<meta name="description">(patch NexT if needed). - Canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content. are emitted and resolve to live HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.' URLs (NexT:
canonical: true). - Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. / Twitter Card tagsTwitter Card tags (now often called \"X Cards\") are <meta name=\"twitter:...\"> tags in a page's <head> that tell X's link-unfurling system what rich preview to build for a shared URL — image, headline, description, and (for player cards) an embeddable frame. The four card types are summary, summary_large_image, app, and player. Every twitter:* property falls back to its og:* equivalent if missing — except twitter:card itself, which has no fallback and must be set explicitly. They are not a Google or Bing ranking factor. present (NexT built-in, or a head-partial edit).
-
BlogPostingJSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal. added (template snippet orhexo-seoplugin). - Category/tag archives handled — noindexed, canonicalized, or kept only as real topic hubs (not left as thin duplicates).
- Paginated archive pages self-canonicalize (page 2 → page 2, not page 1).
- Theme JS/CSS audited in LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal.; minifier + lazy-load image plugins considered.
- GitHub Pages:
CNAMEinsource/, HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.' enforced, deploy via Actions to avoid CNAME reset. - Baidu sites: not on GitHub Pages; Baidu verification + Baidu sitemap + URL push configured.
- No URL ever changed without a 301 redirectA 301 redirect is the HTTP status code for a permanent move: it tells browsers and search engines a URL has moved for good, and it's the strongest signal for consolidating a page's ranking signals onto the new URL. Google says permanent redirects don't cause a loss in PageRank. in place.
Hexo SEO — cheat sheet
On by default vs. you must add it
| SEO feature | Hexo default | How to get it |
|---|---|---|
| Static HTML / crawlable content | Yes | hexo generate |
Crawlable <a href> links | Yes | theme templates |
| XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. | No | hexo-generator-sitemap |
| robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere. | No | hexo-generator-robotstxt or manual file |
| RSS feedAn RSS or Atom feed is an XML file listing a site's most recently published or updated URLs. Search engines accept it as a sitemap-style discovery signal for fresh content — not a replacement for a full XML sitemap. | No | hexo-generator-feed |
| Per-post meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through. | No (theme-dependent) | description: + theme patch |
| Canonical tagA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content. | No (theme-dependent) | NexT canonical: true |
| Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. / Twitter Card | No (theme-dependent) | NexT built-in or head-partial edit |
| Structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding. (JSON-LDJSON-LD (JavaScript Object Notation for Linked Data) is a script-based structured data format, typically paired with the schema.org vocabulary to describe page content for search engines and AI systems. Google recommends it over Microdata and RDFa because it's the easiest format to implement and maintain at scale — but all three work, and structured data isn't a ranking signal.) | No | template snippet or hexo-seo plugin |
| Stable permalinks | No (date/filename based) | hexo-abbrlink |
| IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it. submission | No | hexo-indexnow (Bing/Yandex, not Google) |
Key _config.yml settings
| Setting | Why it matters |
|---|---|
url: | Base for canonical, sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., RSS, paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. — wrong value breaks all of them |
root: | Subdirectory path for a subdirectory deploy — required alongside url: or root-relative links break |
permalink: | Default is date-based; :title/ is cleaner; never change after publishing; avoid the non-persistent :id token |
meta_generator: false | Removes the <meta name="generator" content="Hexo"> tag |
Plugin install commands
npm install hexo-generator-sitemap --save
npm install hexo-generator-robotstxt --save
npm install hexo-generator-feed --save
npm install hexo-abbrlink --save
npm install hexo-indexnow --saveFast facts
- Hexo output skips Google’s Wave 2 renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. queue — content is in the first fetch.
lastmodcomes from theupdatedfield (falls back todate) — keep it current.<meta name="keywords">is ignored by Google (since 2009) — organizational only.- Category/tag archives are auto-generated and thin → noindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. or canonicalize.
- Baidu can’t crawl JS well → static Hexo is an advantage, but GitHub Pages is blocked in China.
Build, serve, and verify a Hexo site
The basic Hexo build loop is the same everywhere; the shell differs.
macOS / Linux
# install dependencies and the SEO plugins
npm install
npm install hexo-generator-sitemap hexo-generator-robotstxt hexo-generator-feed --save
# clean stale output, then build the static HTML
npx hexo clean && npx hexo generate
# preview locally before deploying
npx hexo server
# confirm the sitemap and robots.txt were actually generated
ls public/sitemap.xml public/robots.txtWindows (PowerShell)
# install dependencies and the SEO plugins
npm install
npm install hexo-generator-sitemap hexo-generator-robotstxt hexo-generator-feed --save
# clean stale output, then build the static HTML
npx hexo clean; npx hexo generate
# preview locally before deploying
npx hexo server
# confirm the sitemap and robots.txt were actually generated
Get-ChildItem public\sitemap.xml, public\robots.txt Confirm content is in the raw HTML (not JS-rendered)
The whole point of Hexo is that content is already in the HTML. Verify it by checking that your post text appears in the raw response, before any JavaScript runs.
macOS / Linux
# fetch the raw HTML and search for a phrase from your post body
curl -s https://yourdomain.com/your-post/ | grep -i "a sentence from your post"
# confirm the canonical tag points at the live HTTPS URL
curl -s https://yourdomain.com/your-post/ | grep -i 'rel="canonical"'Windows (PowerShell)
# fetch the raw HTML and search for a phrase from your post body
(Invoke-WebRequest https://yourdomain.com/your-post/).Content | Select-String "a sentence from your post"
# confirm the canonical tag points at the live HTTPS URL
(Invoke-WebRequest https://yourdomain.com/your-post/).Content | Select-String 'rel="canonical"'If the phrase shows up in curl/Invoke-WebRequest output, it’s in the static HTML
and Google sees it on Wave 1 — exactly what you want.
Patrick's relevant free tools
- Google Index Checker — Check one URL’s observable indexability blockers, or reconcile sitemap, crawl, and supplied Search Console evidence across a URL set before verifying Google’s actual state in URL Inspection.
- XML Sitemap Validator — Paste, upload, or fetch a sitemap by URL — errors, warnings, and a health score with line numbers. Pasted and uploaded sitemaps are validated entirely in your browser.
- hreflang Generator + Linter — Enter your URL × locale matrix and get bidirectional hreflang markup as head tags, sitemap XML (auto-split past 50,000 URLs), and Link headers — linted live for wrong region codes, duplicates, and missing fallbacks. Runs entirely in your browser.
Tools for Hexo SEO
Hexo plugins (the SEO toolkit)
- hexo-generator-sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. — the official XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags. generator; reads
lastmodfrom theupdatedfield. - hexo-generator-robotstxt — generates
robots.txtwith a sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. pointer. - hexo-generator-feed — RSSAn RSS or Atom feed is an XML file listing a site's most recently published or updated URLs. Search engines accept it as a sitemap-style discovery signal for fresh content — not a replacement for a full XML sitemap./Atom feed for aggregators and Google News eligibilityGoogle News SEO is the practice of getting eligible for and ranking well in Google's news-specific surfaces — the News tab of Search and the Top Stories carousel. As of the 2024–2025 Publisher Center transition there's no application to file: content that complies with Google's news content policies is automatically eligible, and ranking within that pool is driven by relevance, prominence, authoritativeness, freshness, usability, and location/language..
- hexo-abbrlink — stable, hash-based permalinks that survive file renames.
- hexo-indexnowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it. / hexo-submit-urls-to-search-engine — push changed URLs to Bing (IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it.) and Baidu respectively.
- hexo-all-minifier / hexo-lazyload-image — Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. helpers.
- hexo-seo — all-in-one option with structured-data generation.
Testing and monitoring
- Google Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. — submit the sitemap, inspect URLsA Google Search Console feature that reports how Google sees one specific URL on a property you own. By default it shows the last-indexed snapshot; a separate \"Test live URL\" mode fetches the current version., watch indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed..
- Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility. — submit the sitemap, configure IndexNow, run Site Scan.
- Baidu Webmaster (Ziyuan) — verification and URL push for Chinese-audience sites.
- LighthouseLighthouse is Google's free, open-source tool that audits a page under simulated lab conditions and scores it 0–100 across Performance, Accessibility, Best Practices, and SEO. It's lab data — useful for debugging, not a ranking signal. / PageSpeed InsightsPageSpeed Insights (PSI) is a free Google tool at pagespeed.web.dev that reports two kinds of data for a URL: real-user field data from the Chrome UX Report and a single Lighthouse lab run with the 0–100 Performance score. Only the field Core Web Vitals are what Google uses for ranking. — audit theme JS/CSS for Core Web VitalsGoogle's three real-user UX metrics — LCP (loading), INP (responsiveness), and CLS (visual stability) — used by Google's ranking systems, with no official weight attached, measured on field data. regressions.
- View Source / curl — confirm content, canonical, and meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through. are in the raw HTML (see the Scripts tab).
Hexo SEO mistakes to avoid
Concrete mistakes people actually make when they set up or migrate a Hexo site — prevention, not diagnosis (see the Troubleshooting tab for that).
Leaving url: as the placeholder or on http://
Publishing with url: http://yoursite.com still set to the scaffold default or the
wrong protocol is why it’s wrong: canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content., the sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., RSSAn RSS or Atom feed is an XML file listing a site's most recently published or updated URLs. Search engines accept it as a sitemap-style discovery signal for fresh content — not a replacement for a full XML sitemap. links, and
paginationPagination splits a large set of content — product listings, blog archives, search results — across multiple sequentially numbered URLs. For SEO, each paginated page should be crawlable, indexable, and self-canonical; Google no longer uses rel=prev/next, but Bing still does. all build off this one value, so every one of them silently points at the
wrong address. What to do instead: set url: to your real live domain with https://
before your first hexo generate, and re-check it any time you move domains.
Renaming a post file (or changing its slug) with no redirect
The default permalink derives the URL from the post’s filename and date, so renaming
the Markdown file or editing the date changes the live URL. Why it’s wrong: every
inbound link and any accumulated ranking signal on the old URL is now pointing at a
404. What to do instead: switch to hexo-abbrlink for a stable hash-based permalink
before you have links to lose, and if you ever must change a published URL, add a 301
redirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't. at your host or CDN.
Shipping without hexo-generator-sitemap and hexo-generator-robotstxt
Assuming a static site generatorA build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers. “just handles” crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. basics is why it’s wrong: a
default Hexo install produces neither a sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. nor a robots.txt — there’s no
sitemap pointer for crawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. to find. What to do instead: install both plugins,
confirm public/sitemap.xml and public/robots.txt exist after hexo generate, and
submit the sitemap in Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. and Bing Webmaster ToolsMicrosoft's free portal for monitoring and improving how a site appears in Bing search — the peer to Google Search Console, plus IndexNow instant indexing, richer backlink data, and keyword volumes. Because Bing's index also feeds Microsoft Copilot, it doubles as a window into AI-search visibility..
Leaving category and tag archives open to indexing at scale
Letting Hexo’s auto-generated category/tag pages accumulate as the post count grows is why it’s wrong: each archive is filled with post excerpts that duplicate the posts themselves, so you end up with hundreds of thin pagesThin content is web content that provides little or no value to users. Google's spam policies name it 'thin content with little or no added value' — and it's about value per page, not word count. competing for the same queries and diluting crawl attention. What to do instead: noindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. the archive templates, self-canonicalize paginated archive pages, or keep a category indexed only when it’s a genuine, curated topic hub.
Assuming hexo-indexnow covers Google too
Installing IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it. and expecting it to speed up Google indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. is why it’s wrong: IndexNow is a Bing/Yandex/Baidu protocol — Google doesn’t consume it for general pages, so you still need a submitted sitemap for Google-side discovery. What to do instead: use IndexNow for Bing/Yandex freshness and rely on the sitemap plus normal crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. for Google.
Deploying to GitHub Pages without a durable CNAME
Relying on hexo-deployer-git alone for a custom domain is why it’s wrong: some
deploy paths reset or omit the CNAME file, which silently drops your custom domain
back to the default github.io address (and breaks HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.' enforcement). What to do
instead: keep a CNAME file in source/ so it ships with every build, and prefer a
GitHub Actions workflow that publishes the built public/ folder intact.
Common Hexo SEO problems
Symptom-first lookup for issues you already have on a Hexo site.
Sitemap.xml returns a 404 after deploy
Symptom: https://yoursite.com/sitemap.xml 404s, or Search ConsoleA free Google service that reports how a site performs in Google Search and surfaces problems with how Google crawls, indexes, and serves it. It's first-party data straight from Google — but you don't need it to appear in results. reports it
couldn’t fetch the sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing..
Likely cause: hexo-generator-sitemap isn’t installed, isn’t listed in
_config.yml, or the public/ build output wasn’t fully deployed (a partial upload
or a deploy step that excludes dotfiles/XML).
Fix + check: run npm install hexo-generator-sitemap --save, add a sitemap:
block to _config.yml, then run hexo clean && hexo generate and confirm
public/sitemap.xml exists locally before deploying. After redeploying, fetch the
live URL directly (curl -I https://yoursite.com/sitemap.xml) and confirm a 200.
Google Search Console shows pages as “Discovered — currently not indexed”
Symptom: Posts are crawlable and load fine in a browser, but Search ConsoleGoogle's free tool for monitoring crawling, indexing, and search performance.’s Page Indexing reportThe Google Search Console report (formerly Index Coverage) showing how many of your URLs are indexed vs. not indexed, and grouping the not-indexed ones by reason. leaves them in “Discovered, not indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed.” for weeks.
Likely cause: thin category/tag archive pages are eating a disproportionate share of crawl attention, or the posts themselves are thin/duplicative of the archives that excerpt them.
Fix + check: noindexNoindex is a directive that tells search engines to keep a page out of their index, so it won't appear in search results. It works only on pages a crawler can actually fetch — a page blocked in robots.txt can never be noindexed. or canonicalize the auto-generated category/tag archives (see the anti-patterns entry above), request indexing on a handful of affected URLs in Search Console, and re-check the Page Indexing reportThe Google Search Console report (formerly Index Coverage) showing how many of your URLs are indexed vs. not indexed, and grouping the not-indexed ones by reason. after a few days to a couple of weeks — this isn’t an immediate signal.
Meta description isn’t showing up in search snippets
Symptom: your post has a description: field in front matter, but Google shows an
auto-generated snippet instead, or view-source: shows no
<meta name="description"> tag at all.
Likely cause: the theme’s head template never prints page.description — this is
the single most common NexT gap, and it affects other themes too.
Fix + check: patch the theme’s head partial to output
<meta name="description" content="{{ page.description or config.description }}">
(NexT-style templating), rebuild, then curl -s https://yoursite.com/your-post/ | grep -i 'name="description"' to confirm the tag is present in the raw HTML before you wait
on a snippet refresh.
Canonical tag is missing or points at the wrong URL
Symptom: curling a post shows no rel="canonical" tag, or it resolves to http://
instead of https://, or to a stale domain.
Likely cause: the theme’s canonical feature isn’t enabled (NexT needs
canonical: true in _config.next.yml), or url: in the main _config.yml is wrong
— canonical tagsA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content. build off that base URL.
Fix + check: confirm url: is correct first, enable the theme’s canonical option,
rebuild, and check with curl -s https://yoursite.com/your-post/ | grep -i 'rel="canonical"' — the value should exactly match the live HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.' URL.
Custom domain reverts to username.github.io after a deploy
Symptom: a working custom domain on GitHub Pages stops resolving after a routine
hexo deploy, falling back to the default github.io address.
Likely cause: the deploy process overwrote or omitted the CNAME file that GitHub
Pages reads to know your custom domain.
Fix + check: put (or restore) a CNAME file containing just your domain in
source/ so it’s copied into every build, redeploy, and confirm in the repo’s
Settings → Pages that the custom domain field still shows your domain with HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.'
enforced.
Baidu isn’t indexing the site at all
Symptom: Baidu Ziyuan (Baidu Webmaster) shows little to no crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor. activity even though Google indexes the site fine.
Likely cause: the site is hosted on GitHub Pages, which is blocked in mainland China, so Baidu’s crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. often can’t reach it consistently.
Fix + check: move Baidu-facing hosting to Gitee Pages, Cloudflare, or a Chinese
CDN, add Baidu site verification and a Baidu-format sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing.
(hexo-generator-baidu-sitemap), then watch the Baidu Ziyuan crawl-frequency report
over the following weeks for renewed activity.
Test yourself: Hexo SEO
Five quick questions on doing SEO with the Hexo static site generatorA build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers.. Pick an answer for each, then check.
Resources worth your time
My related writing
- JavaScript SEO: A Definitive Guide — renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., DOM parityWhether the rendered DOM matches what you expect the raw HTML to become., and why static/pre-rendered output is the low-risk end of the spectrum.
- The Beginner’s Guide to Technical SEO — where renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. architecture fits in the bigger picture.
My speaking
- How Search Works (SlideShare) — my walkthrough of crawlingCrawling is how search engines use automated bots (like Googlebot and Bingbot) to discover URLs and download pages. A page has to be crawlable to be indexed, but crawling on its own isn't a ranking factor., rendering, indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed., and ranking. (My standing disclaimer applies: “This is my understanding of systems… not going to be 100% complete or accurate.”)
From around the industry
- Hexo documentation — the official docs for config, permalinks, front matter, and deployment.
- hexo-generator-sitemap — the official sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. plugin README.
- NexT theme SEO settings — canonical, webmaster verification, and Open GraphOpen Graph (OG) tags are `<meta>` elements in a page's head, defined by the Open Graph protocol (ogp.me, created by Facebook), that describe a page as a shareable object — its title, description, image, URL, and type. They control how a link preview card looks when the page is shared on Facebook, LinkedIn, Slack, Discord, WhatsApp, and iMessage. They are not a direct Google ranking factor, though Google reads og:title, og:image, and og:site_name as inputs to how a result appears. for the most-used theme.
- Google — JavaScript SEO basics — the crawl → render → index phases a static build lets you skip for content.
- Bing — Keeping Content Discoverable with Sitemaps — XML preference,
lastmodaccuracy, and IndexNowIndexNow is an open push protocol that lets you instantly tell participating search engines (Bing, Yandex, Naver, Seznam, and Yep) which URLs you've added, changed, or removed via a simple HTTP request — and one submission is shared across all of them. Google does not use it.. - John Mueller — Some design decisions — how he runs his own static blog (sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. + RSSAn RSS or Atom feed is an XML file listing a site's most recently published or updated URLs. Search engines accept it as a sitemap-style discovery signal for fresh content — not a replacement for a full XML sitemap. + Article structured dataArticle schema (Article, NewsArticle, or BlogPosting) is structured data marking up a written piece's headline, author, and dates — Google labels it the \"Article rich result,\" but it's a better-displayed existing result, not a distinct new card, and it isn't required for Top Stories or Discover eligibility.), and why switching generators isn’t itself an SEO win.
Hexo SEO
Hexo SEO is the practice of optimizing sites built with Hexo, the Node.js static site generator. Hexo outputs pure static HTML at build time, so content is crawlable on the first fetch — but sitemaps, robots.txt, meta descriptions, canonicals, and structured data all depend on plugins and theme configuration.
Related: JavaScript SEO
Hexo SEO
Hexo is an open-source, Node.js-based static site generatorA build tool that pre-renders every page into static HTML files at deploy time, so the server delivers complete HTML without executing code per request — eliminating JavaScript rendering delays for search engine crawlers. and blogging framework that compiles Markdown and theme templates into pure static HTML at build time. Every page produced by hexo generate is a pre-rendered HTML file — no database queries at request time, no server-side renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM., and no client-side JavaScript needed to expose content to crawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index.. That puts Hexo in the same “fully pre-rendered” category as Hugo and Jekyll: GooglebotGooglebot is Google's web crawler — the software that fetches pages so Google can index and rank them. It comes in two variants, Googlebot Smartphone (primary, under mobile-first indexing) and Googlebot Desktop, and runs an evergreen Chromium renderer. gets complete HTML on the first fetch, with no renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. queue (Wave 2) delay.
Hexo SEO is the work of making that static output actually rank. The static HTML is a crawlabilityCrawlability is how well search engine crawlers can discover, access, and fetch a site's pages. A crawlability issue is any technical condition — blocked access, broken links, server failures, or bloated URL inventory — that stops pages from reaching the index. floor, not a finished SEO setup. Out of the box, most Hexo themes ship no XML sitemapAn XML sitemap is a UTF-8 file listing the canonical URLs on your site (with optional lastmod) so search engines can discover and prioritize them. It's a discovery and diagnostic aid, not a guarantee of indexing — and Google ignores its priority and changefreq tags., no robots.txt, no per-post meta descriptionThe meta description is an HTML head tag — `<meta name=\"description\" content=\"…\">` — that suggests a short summary of the page for the search snippet. It's not a Google ranking factor, and Google rewrites it the majority of the time, but a good one can still lift click-through., no canonical tagA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content., and no structured dataStructured data is a standardized way of labeling page content (using the schema.org vocabulary in JSON-LD, Microdata, or RDFa) so search engines can understand its meaning. It's not a direct ranking factor — its value is rich results and entity understanding.. Each of those is added through _config.yml settings, front matter fields, theme template edits, or npm plugins — hexo-generator-sitemap for sitemapsA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing., hexo-generator-robotstxt for robots.txtA plain-text file at the root of a host that tells crawlers which URLs they may and may not request. It controls crawling, not indexing — a blocked URL can still be indexed if it's linked from elsewhere., hexo-generator-feed for RSS, and hexo-abbrlink for stable permalinks.
The recurring gotchas are configuration ones: the url: value in _config.yml must match your live HTTPSHTTPS is the encrypted version of HTTP — it uses TLS to authenticate the server and protect data in transit between a browser and a website. Google announced it as a lightweight ranking signal in 2014 and today conditionally prefers HTTPS pages as canonical; Chrome marks plain HTTP pages 'Not Secure.' domain or canonicals and sitemapA sitemap is a file that lists the pages, images, videos, and other files on your site so search engines can discover them. It helps discovery, but submitting a sitemap doesn't guarantee crawling or indexing. links break; the default :year/:month/:day/:title/ permalink ties URLs to filenames and dates, so a rename breaks links without a 301; and auto-generated category and tag archives can create thin or duplicate contentThe same or very similar primary content reachable at more than one URL. There's no general duplicate content penalty — the real costs are possible signal dilution, the wrong URL getting chosen, and less-efficient crawling.. Hexo is also popular in the Chinese developer community, where its static output removes a real obstacle for Baidu, whose crawlerA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. handles JavaScript poorly — though that’s a crawlabilityCrawlability is how well search engine crawlers can discover, access, and fetch a site's pages. A crawlability issue is any technical condition — blocked access, broken links, server failures, or bloated URL inventory — that stops pages from reaching the index. advantage, not proof of Baidu indexingStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. or ranking.
Related: JavaScript SEO
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Revision history
Compare the published article with an archived editorial snapshot. Added and removed words are shown only after you open a comparison.
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Added Hexo config/permalink/theme details that top-ranking pages miss: root: for subdirectory deploys, url_for vs full_url_for, the non-persistent :id permalink token, the separate trailing_index/trailing_html controls, theme-vs-plugin tag-ownership conflicts, and the generator API's route inventory — plus a hedge on the Baidu-indexing claim.
Change details
-
Documented root: for subdirectory deployments and the url_for/full_url_for distinction in the _config.yml section.
-
Added the non-persistent :id permalink token warning and the trailing_index/trailing_html distinction to the Permalinks section.
-
Added guidance on picking one owner (theme or plugin) per metadata tag category to avoid duplicate canonical/OG/JSON-LD output.
-
Explained that category/tag/pagination routes come from Hexo's generator API, not source/ files, and can expand silently after a theme or plugin update.
-
Hedged the Baidu section: static output is a crawlability advantage, not proof of Baidu indexing or ranking; verify directly in Baidu Ziyuan.