BTST
PluginsQuickstartDocs
Live Blog

From research to product evaluation

Evaluating a publishing workflow for an app you already own?

See what the BTST Blog plugin adds to an existing React or Next.js app
BTST

Open-source TypeScript features for the React application, data, and deployment you already own.

Released plugins

  • Blog
  • AI Chat
  • CMS
  • Form Builder
  • UI Builder
  • Kanban
  • Comments
  • Media
  • Route Docs
  • OpenAPI
  • Better Auth UI

Resources

  • Quickstart
  • Documentation
  • All plugins
  • Live Blog
  • GitHub (opens in a new tab)
© 2026 BTST. Open source under the MIT License.
AI Chat
September 10, 2026TanStackBlogSEO

TanStack Start Blog SEO: Server HTML, Canonicals, and Sitemaps

Verify server-rendered article content, canonical URLs, public sitemap entries, and Search Console evidence for a TanStack Start blog.

TanStack Start Blog SEO: Server HTML, Canonicals, and Sitemaps

A TanStack Start blog can look complete in your browser while its initial HTML contains only navigation and a loading state. It can also render a full article at an address that disagrees with its canonical URL or sitemap. These are separate problems; checking them separately makes an SEO investigation much faster.

This guide is for an existing blog. If you are still choosing an installation path, begin with the TanStack Start Blog walkthrough and the current framework setup. For an installed site, verify one published article from data access through the HTTP response before changing titles across the library.

First check what the server sends#

Use an anonymous request to a production article. Inspect the HTML response itself, not just the browser's hydrated DOM. Look for the article's heading and a distinctive sentence from its body outside scripts and serialized data.

This small Node script fetches a page and checks those basic conditions. Replace the example URL and sentence with a published article you control:

JS
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
import assert from "node:assert/strict";

const url = "https://example.com/pages/blog/my-article";
const sentence = "A distinctive sentence from the article.";
const response = await fetch(url);
assert.equal(response.status, 200);
const html = await response.text();
const visible = html
  .replace(/<(script|style|template)\b[^>]*>[\s\S]*?<\/\1>/gi, " ")
  .replace(/<[^>]+>/g, " ");
assert.match(visible, /my article/i);
assert.ok(visible.includes(sentence));
console.log("Article text is present in the server response.");

This is a smoke check for known content, not a general HTML parser or indexing test. Entity encoding and nested markup can require a DOM parser for exact text comparisons. A passing check proves neither Google indexing nor search performance.

If the article appears only after hydration, trace the server loader and any identity-dependent loading guard. Public content should be loadable for an anonymous identity. Waiting for a browser session hook before rendering an already-public article can defeat the server rendering you expected.

Align the loader, head metadata, and public URL#

TanStack Start provides server rendering and route head management, but your integration must supply the right content. Follow the Start SEO guide for the framework's head and rendering model.

For BTST v3, keep these configuration values distinct:

SettingExampleUsed for
Site originhttps://example.comPublic links and canonical addresses
Site base path/pagesMounted UI routes
API originYour configured backend originServer-side API calls
API base path/api/dataPlugin HTTP endpoints

Set shared runtime values once in createClientStack(). A development origin in the site settings can produce technically valid metadata pointing to the wrong host. An unreachable API origin can break server loading even when browser requests work through a relative URL.

Forward request headers only through the intended server integration to a trusted backend. Use a fresh QueryClient for each server request. Do not share one user's cached private data with the next request.

For one article, compare the final response URL, canonical link, Open Graph URL, and sitemap location. They should identify the same public article. Also check a direct request to a missing slug; a branded error page returning success is not the same as a real missing-resource response.

Build the sitemap from published content#

A sitemap should contain canonical public URLs. Keep private drafts, edit forms, and account settings out of a blog's public-content list. With BTST, the resolved client stack exposes generateSitemap() for registered plugins; integrate that result with your site's other canonical pages using the framework setup documented in installation.

Verify the generated XML in production. It is easy to check a local sitemap against the local database and miss that production still uses an old deployment, a different database, or an incorrect site origin.

A newly published post should have a stable slug, appear in the public article list, and be reachable through a normal internal link. Sitemaps help discovery; they do not replace useful navigation or make an otherwise private page public. Google's sitemap guidance explains how sitemaps support discovery without guaranteeing crawling or indexing.

Separate rendering failures from indexing outcomes#

Use a short evidence table for each suspect URL:

CheckWhat it establishes
Anonymous HTTP response includes article textServer rendering works for that request
Canonical and sitemap matchYour URL signals agree
Public index links to the postAn ordinary visitor can discover it
Search Console URL InspectionGoogle's reported index and crawl state
Finalized search impressions and clicksSearch visibility and visits over the reported dates

A request for indexing is not confirmation of indexing. Likewise, a page with no clicks may still be indexed. Fix reproducible rendering or canonical defects first, then allow time for crawling and compare complete Search Console windows.

For the publishing feature itself, see the Blog plugin's responsibilities and demo. Keep the installation guide focused on setup and use this verification sequence when a deployed article does not appear as expected.

In This Post

First check what the server sendsAlign the loader, head metadata, and public URLBuild the sitemap from published contentSeparate rendering failures from indexing outcomes