Markdown for every page
Each post, changelog entry and index page also exists as Markdown, with a short header (URL, date, authors, version, tags) and absolute links. Agents can fetch it in two ways:.mdURL: add.mdto any URL, for examplehttps://acme.com/blog/launch.mdorhttps://acme.com/blog/index.md.Acceptheader: request the normal URL withAccept: text/markdown, while browsers still get HTML.
<link rel="alternate" type="text/markdown"> and a Link response header, and responses carry Vary: Accept, so caches keep the two apart. The Markdown version names the HTML page as its canonical URL, so search engines never list it in place of the page.
A page that doesn’t exist answers with a real 404, and agents that ask for Markdown or request a .md URL get the error as Markdown with links to the section index and llms.txt.
llms.txt
llms.txt starts with a short note on how to cite the site, lists every published page with a link to its Markdown, a one-line summary (thedescription, or the first paragraph) and its date, and ends with links to llms-full.txt, the feeds and the sitemaps. llms-full.txt contains all pages in one file.
If you forward paths from your own website,
/llms.txt belongs to your website, so link the section files from your own llms.txt or forward /llms.txt to Notra too. Notra leaves out drafts and posts with noindex: true. A public/llms.txt in your repository replaces each section’s generated llms.txt, and the root one when a section lives at /.
Search engines and structured data
robots.txtallows search engines and AI crawlers (GPTBot, ClaudeBot, PerplexityBot and others) on your canonical address and links tollms.txtand the sitemaps. Once a custom domain is the primary address,robots.txton your Notra address disallows all crawling, and every page names the canonical address, so the same post is never indexed twice.- Notra marks previews, drafts,
noindex: trueposts and 404 pagesnoindex. - Each section has a sitemap (
/blog/sitemap.xml) with the last change of every page and an RSS feed (/blog/feed.xml) with summaries, authors and tags, and every page links to the feeds of both sections. - Every page includes schema.org data:
BlogPostingfor posts andTechArticlefor changelog entries (headline, description, publish and update dates, authors, image),BlogorCollectionPagefor the indexes, breadcrumbs and your company as publisher (name,logoand the profiles infooter.socials). - Open Graph and X tags use the post’s
image. Without one, Notra generates a share image and uses your logo only whenthumbnails.enabledisfalse. Use a PNG or JPEG forimage, because social networks don’t show SVG. The X account comes from the firstfooter.socialslink to x.com or twitter.com. - Pages without a
descriptionuse their first paragraph for search results and link previews.
AI traffic analytics
Every site counts its own visits with nothing to install. Notra counts page views as the site serves them, without cookies, and adds a small script from the site’s own address (/blog/_notra/insights.js) that measures how long each page stays visible.
- The site’s Analytics page shows people, time on page and AI agents on that site, and visits show up about a minute after they happen.
- Settings → Danger zone → Turn off analytics stops counting and removes the script from every page. Data collected so far stays, and Turn on analytics starts counting again.
- AI crawlers, AI agents and visitors arriving from ChatGPT, Claude, Perplexity and other assistants also show up on the GEO Traffic page, under the project the site belongs to.
- Notra reports visits under the site’s primary address, so a page forwarded from
acme.com/blogcounts asacme.com/blog. - If your website also runs the Notra tracker and forwards paths to the site, the site’s report is the one that counts, so Notra never counts the same page view twice.
- Notra never counts previews and views from the Notra dashboard.
When you forward paths through your own host, keep the request’s
Accept, User-Agent and Referer headers and send the visitor’s IP in X-Forwarded-For. See What the rewrite has to do.