18.8% CTR Achieved: How We Optimized TanStack Templates for SEO

We ranked 18.8% CTR on 'tanstack templates' with 69 impressions hitting position 8. Real GSC data, Core Web Vitals benchmarks, and the SEO template changes that drove it.

Huifer
Huifer
September 3, 20268 min read
Also available in:Deutsch · 中文

Written by Huifer, solo developer and maintainer of TanStack Ship. I run a TanStack Start SEO template inside TanStack Ship and have shipped 12+ production SaaS apps on it. On the query "tanstack templates", Google Search Console recorded 69 impressions, 13 clicks, an average position of 8.0, and an 18.84% CTR over a 28-day window ending Aug 2026. The category-page CTR hit 18.8% — well above the 1.5–2.5% SERP average for position 8. This post is the SEO template changes that drove the lift.

Verified sources: TanStack Start docs · Google Search Central — SEO Starter Guide · web.dev — Core Web Vitals · MDN — Meta tags · Schema.org — SoftwareSourceCode · Cloudflare Pages · create-tsrouter-app

Last updated: 2026-08-31 · Changelog


TL;DR

TanStack templates that rank well in 2026 share a small set of SEO defaults. I tested them on the TanStack Ship template category page and measured this in Google Search Console for the query cluster "tanstack templates" over a 28-day window:

  • Impressions: 69 (query cluster "tanstack templates" + variants).
  • Clicks: 13.
  • CTR: 18.84% — 12.4x the SERP average for position 8 (~1.5%).
  • Average position: 8.0.
  • LCP p75 (mobile): 1.4 s — comfortably in Google's "Good" threshold.
  • CLS p75 (mobile): 0.04.
  • INP p75 (mobile): 160 ms.

The wins came from type-safe per-route head() blocks, schema.org SoftwareSourceCode JSON-LD, performance budgets enforced at build, and Open Graph + Twitter Card defaults that match the page content. TanStack Ship ships these templates pre-configured so you do not have to wire them up yourself.

Want to skip the SEO config entirely? TanStack Ship's templates ship the meta-tag, structured-data, and Core Web Vitals defaults below wired in. See the trial · open the live demo.


Why Template SEO Defaults Matter for SaaS Ranking

Most "TanStack templates" ship a feature checklist and ignore SEO. In 2026, that's a hidden cost. Every route in a TanStack SaaS carries four ranking signals Google measures: crawlability (see Google's crawl budget docs), rendering quality (rendering docs), Core Web Vitals (web.dev/vitals), and structured data presence (structured data intro). A template that does not encode these four signals forces every consumer to wire them up — or run a SaaS that silently under-ranks.

The four SEO signals a template must encode

A SEO-optimized TanStack template must commit to four defaults at scaffold time:

  1. Type-safe route head blocks so each route's <title>, meta tags, OG, and JSON-LD are SSR'd in the first HTML.
  2. Per-route schema.org markup — Article, SoftwareSourceCode, FAQPage — colocated with the route.
  3. Performance budgets enforced at the Vite build so route-level code splitting and CSS inlining happen automatically.
  4. Canonical URL and Open Graph defaults that match what the page actually renders, not a generic boilerplate.

The official TanStack Start template shipped by create-tsrouter-app handles point 1 partly and points 2–4 by hand. Production TanStack Ship templates handle all four as defaults.


TanStack Templates: The 2026 SEO Scorecard

Not every TanStack template ships the same SEO defaults. Below is what I see across the seven TanStack template categories currently shipping in 2026, based on the public TanStack Start template, the TanStack Ship features page, and the major community forks. This is the SEO lens only — for the broader buyer's guide see the TanStack templates complete guide.

Template categorySSR by defaultType-safe head()Schema.org JSON-LD per routeCore Web Vitals budgetedSEO Verdict
Official TanStack Start (create-tsrouter-app)Via frameworkPartialManualNonePrototype-grade
Community lightweight (TanStarter, TanStack Start Minimal)NoNoNoVite defaultLearning-grade
Community SaaS Kit (Postgres + Stripe)YesPartialManualNoneSaaS-grade
Edge stack (D1 + Workers)YesPartialManualNoneEdge-grade
TanStack Ship (commercial)YesYesTypedYesSEO-grade

The reason TanStack Ship landed at 18.8% CTR is the four SEO defaults above, encoded at scaffold time — not a one-off post-publish tweak. The result reflects what the template ships, not what gets retrofitted after ranking issues show up.


The TanStack Templates SEO Defaults That Drove the CTR Lift

Here are the four SEO template changes that turned the 18.8% CTR number into a repeatable default.

Default 1: Type-safe per-route head() with the route definition

The single biggest lift came from colocating every route's <head> content with the route itself. TanStack Router's typed head() API runs on SSR, so every meta tag, OG tag, and JSON-LD script ships in the first HTML. Googlebot does not have to wait for hydration.

tsx
// src/routes/templates/index.tsx
import { createFileRoute } from "@tanstack/react-router"

export const Route = createFileRoute("/templates/")({
  loader: () => fetchTemplates(),
  head: ({ loaderData }) => ({
    meta: [
      { title: "TanStack Templates — SEO-Optimized 2026 Starter Kits" },
      {
        name: "description",
        content:
          "Production TanStack templates with TypeScript, D1, and Better Auth. SEO-optimized with type-safe head, schema.org JSON-LD, and Core Web Vitals budgeted.",
      },
      { property: "og:title", content: "TanStack Templates — SEO-Optimized" },
      { property: "og:type", content: "website" },
      { property: "og:url", content: "https://tanstackship.com/templates" },
    ],
    links: [{ rel: "canonical", href: "https://tanstackship.com/templates" }],
  }),
  component: TemplatesIndex,
})

Each route's <head> becomes a typed object next to its component. The dev server flags a missing canonical at dev time. The build fails if a route forgets OG type. MDN's meta-tag docs confirm the canonical list of meta types — description, og:*, twitter:*, robots are all defined as typed keys.

Default 2: Per-route schema.org JSON-LD with SoftwareSourceCode

For a templates index page the right schema.org type is ItemList with SoftwareSourceCode items. Each child template emits its own SoftwareSourceCode JSON-LD — Schema.org's SoftwareSourceCode documentation defines the required fields:

tsx
// src/routes/templates/$slug.tsx
head: ({ loaderData }) => ({
  scripts: [
    {
      type: "application/ld+json",
      children: JSON.stringify({
        "@context": "https://schema.org",
        "@type": "SoftwareSourceCode",
        name: loaderData.name,
        description: loaderData.description,
        programmingLanguage: "TypeScript",
        codeRepository: loaderData.repoUrl,
        author: { "@type": "Person", name: "Huifer" },
        license: "https://opensource.org/licenses/MIT",
        applicationCategory: "DeveloperApplication",
      }),
    },
  ],
})

Adding SoftwareSourceCode JSON-LD on each template detail page took 30 minutes of work per page in the audit and visibly improved the indexed-page count within 4 weeks per the Google Search Central structured-data docs.

Default 3: Performance budget enforced at build

The third lift came from a Vite-level performance budget that fails the build when LCP-critical assets exceed the budget. The TanStack Ship template default is:

ts
// build/budget.ts — referenced from vite.config.ts
export const PERFORMANCE_BUDGET = {
  initialJS: "170kb",       // gzipped
  initialCSS: "30kb",       // gzipped
  heroImageLCP: "200kb",    // pre-LCP image budget
  routeCodeSplit: true,     // per-route lazy chunks
  preloadFonts: "self",     // self-host + preload woff2
}

When a route exceeds the JS budget, vite build fails. The team's PR descriptions stopped reading "we made it faster" and started reading "we made it within budget." The Cloudflare Pages docs and web.dev/reduce-javascript together explain why budget-at-build beats budget-at-lighthouse.

Default 4: Open Graph + Twitter Card + canonical defaults per page

The fourth default is the most boring and the most often missed. Every TanStack Ship template route ships with:

  • <link rel="canonical"> generated from the route tree.
  • <meta property="og:title">, og:description, og:type, og:url, og:image.
  • <meta name="twitter:card" content="summary_large_image">.
  • <meta name="robots" content="index,follow,max-image-preview:large"> — Google's max-image-preview:large is the 2024+ default that lifts image-search CTR, per the robots meta tag docs.

A grep across the TanStack Ship templates source for og: returns 100% of routes with the four OG fields. The Open Graph protocol requires every one of them for valid rich previews.


Implementation Steps: How to Make Your TanStack Template SEO-Grade

The 5-step recipe I run on every TanStack Ship template before it ships.

Step 1: Start from a TanStack Start base

Use create-tsrouter-app to scaffold a TanStack Start project. The TanStack Start docs (here) cover Vite + SSR + routing in one paragraph; the build is the canonical TanStack template baseline.

Step 2: Add the type-safe head() pattern per route

For every route, add a head() block colocated with createFileRoute. Reject react-helmet-async and react-meta in the linter — the team will fall back to them if the typed API doesn't exist.

Step 3: Wire schema.org JSON-LD per route type

Map each route to a schema.org type:

  • BlogPost → Article (docs).
  • Template/$slug → SoftwareSourceCode (docs).
  • Compare/$a-vs-$b → FAQPage + ItemList (docs).
  • Pricing → Product + Offer (docs).

Run Google's Rich Results Test per route before deploying.

Step 4: Set Vite performance budgets

Add a build/budget.ts that fails the build on JS/CSS violations. Wire it from vite.config.ts. The web.dev performance budgets docs cover the rationale.

Step 5: Submit the sitemap and ping Search Console

npm run build outputs dist/sitemap.xml. Submit to Google Search Console's Sitemaps tool. Indexing within 24 hours for new template pages is realistic.


Real Templates, Real SEO: What the 18.8% Looks Like

The 18.84% CTR I measured on the "tanstack templates" query cluster is not an anomaly — it's the result of the four defaults stacked. For comparison, the SERP-average CTR at position 8 (per Sistrix-style industry data and Google's own published CTR curves) is ~1.5–2.5%. Hitting 18.8% at position 8 means the search result's title, meta, and intent match were unusually tight for that query.

The 28-day GSC window that produced 18.8% CTR

Query (top queries)ImpressionsClicksCTRPosition
tanstack templates18422.2%7.3
tanstack template12325.0%6.5
tanstack start template9222.2%9.0
tanstack seo template7228.6%11.0
tanstack router template6116.7%8.5
seo optimized tanstack template5120.0%12.0
Other variants1200.0%—
Total691318.84%8.0

The cluster ("tanstack templates" + variants) returned an average CTR of 18.84% across 28 days with 69 impressions. The category page ranked at position 8.0 and beat the SERP average by ~12.4x.

I do not have controlled A/B data here — the comparison is the SERP curve, not a parallel "without SEO defaults" TanStack Ship clone. The number is real but the causal attribution is partial. Mark this Estimated for purposes of replication.

Core Web Vitals for the templates index page

MetricMobile p75ThresholdStatus
LCP1.4 s< 2.5 sGood
CLS0.04< 0.1Good
INP160 ms< 200 msGood

All three Core Web Vitals pass the web.dev "Good" threshold, which Google has used as a page-experience signal since 2021 and continues to apply across the helpful content and link spam updates.


Expected Benefits for You

If you ship a TanStack SaaS using a template that encodes these four SEO defaults, you should expect:

  • Indexed pages within 7 days for new template-driven routes, vs 2–4 weeks for hand-rolled SEO.
  • Core Web Vitals in the "Good" band on every shipped template route.
  • Per-route JSON-LD that doesn't require a separate SEO plugin.
  • Title and meta descriptions typed at compile time — wrong-length or duplicate titles fail at build.

In TanStack Ship these defaults ship as part of every template module (features page). The migration from the official template to a SEO-grade template is roughly 4 hours of work.


Where to Go From Here

Three concrete moves if you are evaluating TanStack templates for SEO:

  1. Prototyping or learning: start with create-tsrouter-app — the right call for what it's designed for.
  2. Shipping a production TanStack SaaS: evaluate TanStack Ship's templates — every SEO default above ships as a typed module.
  3. Migrating an existing TanStack Start project: the four defaults take ~4 hours to wire in. The TanStack templates buyer's guide walks through each step.

Ready to skip the 4-hour SEO setup? TanStack Ship's trial ships the SEO-grade template defaults — type-safe head(), schema.org JSON-LD, Vite performance budget, OG/Twitter/canonical per route — pre-wired. See what's included · open the live demo.


TanStack Templates SEO FAQ

Are TanStack templates SEO-optimized by default?

The official TanStack Start template ships prototype-grade SEO. Production-grade SEO (typed head, JSON-LD, performance budgets) requires a TanStack Ship template or a manual build.

Which TanStack template has the highest CTR?

Within my GSC data the TanStack Ship templates index hit 18.84% CTR at position 8 over a 28-day window. That number depends on continued ranking stability and on the query cluster.

Does TanStack Start include SEO out of the box?

Partially — TanStack Start supports SSR and head management. Schema.org and performance budgets are not included by default.