Analytics and SEO
The theme loads no analytics, form or advertising script by default, and makes
no outbound request until configured. Connecting one takes explicit
configuration, and that external data boundary belongs in the site’s privacy
statement. SEO is the opposite: canonical, hreflang, the robots meta, Open
Graph and Twitter cards are generated per page by the theme, and what you have
to get right is baseURL and each page’s description.
Connecting Google Analytics
Use Hugo’s built-in service configuration with a GA4 measurement ID:
The theme renders that script in the production environment only (a hugo
build defaults to production, and hugo server to development). Local previews
and preview deployments therefore report nothing, and need no extra switch.
Do not also set the deprecated top-level googleAnalytics key. Where analytics
is not wanted, delete the block rather than filling in a fake ID.
Once configured, page views and events go to Google. A strict same-origin Content Security Policy also has to permit it — see Content Security Policy. This is a site decision, not a theme default.
Connecting another analytics service
Plausible, Umami, Matomo and the like need only a script inserted. The theme provides two injection points; create a file of the same name in the site repository and no theme change is needed:
Do not omit the hugo.IsProduction guard: without it, everyone’s local preview
reports into your analytics.
That is deliberate: a cookie consent script has to run before the analytics script to actually hold it back.
The “was this page helpful?” feedback widget is a separate matter: off by default, making no network request, and configured in Repository links and page info.
Page descriptions
<meta name="description"> takes the first non-empty value of:
- The page’s
descriptionfront matter - The page summary Hugo computes (
.Summary) params.descriptionin the site configuration
Writing one description per page is the only SEO action an author has to take.
It serves three purposes at once: the search engine snippet, the card subtitle
on a section index, and the result preview in site search.
A multilingual site writes one per language; do not copy the English description onto a Chinese page. The site-level default is per language too:
canonical and hreflang
The theme emits one canonical and a set of hreflang alternates per page, with
no configuration:
The hreflang codes come from each language’s locale (en-US / zh-CN on
this site), and the links from Hugo’s translation relationships. Where a page
has no counterpart in the other language, Hugo cannot find a translation and
falls back to that language’s home page. That is expected behaviour, and it also
tells you whether Hugo recognized the translation pairing.
The canonical is assembled from baseURL. A wrong baseURL points search
engines at addresses that do not exist, which is harder to notice than a build
failure. Run through the
deployment checklist before launching.
Full multilingual configuration is in Languages.
Social cards
The theme calls Hugo’s built-in Open Graph and Twitter card templates, and the title, description, URL, language and site name are all automatic:
To give a shared link an image, set images in front matter:
For a site-wide fallback, write the same key under params:
With an image, twitter:card changes from summary to summary_large_image
and og:image and twitter:image appear. This site sets neither, which is why
the rendered output above has no image tags.
Sitemap
Hugo generates it automatically, and a multilingual site gets an index:
Both the site default and per-page overrides are Hugo’s own:
changefreq and priority are hints rather than promises, and a search engine
may ignore them. What is worth doing before publishing is confirming that
drafts, private content and non-canonical copies stayed out of the sitemap, and
that each language’s file was generated.
robots.txt and staying unindexed
Hugo generates robots.txt only when the site configuration turns it on:
The template the theme supplies gives two results by build environment, with no content for you to write:
The robots meta in the page follows the same switch: index, follow in
production and outside print output, noindex, nofollow otherwise. Do not build
preview deployments with --environment production; a non-production build
declines indexing by itself.
The theme has no per-page noindex switch. Where a page should not be indexed,
the reliable answer is not to publish it (draft: true, or Hugo’s _build
options). To publish it and still keep it out, emit your own tag through the
head-end.html hook; the theme already emits one robots meta, and how a
search engine reconciles two is its own decision.
Checking indexing
A week or two after launch, confirm in this order that what search engines see matches what you think:
- Crawl permission: open
<baseURL>/robots.txtand confirmAllow: /rather thanDisallow: /. - Page inventory: open
<baseURL>/sitemap.xml, follow into a language sitemap, and check the page count. - Indexed count: search
site:yourdomainand check the order of magnitude; a page-by-page reconciliation is not needed. - Canonical addresses: results should land on the canonical URL, not a version with a
?parameter or an old domain. - Active submission: add the site in Google Search Console / Bing Webmaster Tools and submit the
sitemap.xmladdress, which is faster than waiting to be crawled.
Search metadata cannot compensate for the content itself: a thin, duplicated or
stale page stays that way however well its description is written.
Verify
Then check these in the output:
Confirm once more in a browser: open a representative page and look at the network panel — a site with no analytics should make no request to a third-party domain.
Related
- Deploy —
baseURL, the checklist, and keeping preview deployments unindexed - Repository links and page info — the feedback widget, edit links and last-modified time
- Languages — language configuration decides
hreflangand translation pairing - AI-agent support — the
.mdoutput andllms.txtwritten for models - Configuration —
services,sitemap,enableRobotsTXTand the rest