Guide SolidJS SEO

How to faire SolidJS sites crawlable, indexable, and fast — pourquoi bare SolidJS is CSR-only, how SolidStart's SSR/SSG fixes it, managing head tags with @solidjs/meta, and pourquoi SolidJS hydrates (it n’est pas resumable comme Qwik).

Première publication : 26 juin 2026 · Dernière mise à jour : 3 août 2026 · Advanced
Langues

SolidJS is a fast, React-like library with fine-grained reactivity and aucun virtual DOM — but on its propre it's client-side rendered, so it ships an vide HTML shell with the même indexation problems as bare React. The fix is SolidStart, the official meta-framework: SSR or SSG put contenu réel and metadata in the premier réponse. Manage head tags with @solidjs/meta (<Title>, <Meta>, <Link>), retourner réel 404s with <HttpStatusCode>, and récupérer données on le serveur with createAsync. Un chose pas to mix up: SolidJS hydrates — it n’est pas resumable. Resumability is Qwik's trick. SolidJS's win is a Core Web Vitals edge on top of standard SSR.

TL;DR — SolidJS is fine-grained reactive (signals, aucun virtual DOM) and ships as a CSR library by par défaut — an vide shell with the même Wave-1 indexation problem as bare React. SolidStart is the fix: SSR, SSG (route prerendering), and streaming SSR put content and metadata in the premier réponse. Manage head tags with @solidjs/meta (<Title>, <Meta>, <Link> sous a <MetaProvider>), retourner réel code d’états with <HttpStatusCode>, and charger données on le serveur with createAsync so it lands in the SSR HTML. The accuracy spine: SolidJS hydrates — it n’est pas resumable (that’s Qwik). Its fine-grained reactivity is a client mettre à jour optimization, pas a server-to-client startup un — so the SEO upside is mostly a Core Web Vitals (INP/TBT) edge layered on top of normal SSR.

Evidence for this claim The article's described solidjs-seo capabilities must be evaluated against the platform's current documentation rather than assumed to be search-engine behavior. Scope: Platform-specific capability documentation. Confidence: high · Verified: SolidStart documentation Evidence for this claim Regardless of platform, Google needs crawlable URLs, accessible rendered content, descriptive metadata, and valid search directives. Scope: Google requirements independent of platform. Confidence: high · Verified: Google Search Central: SEO Starter Guide

SolidJS architecture: what’s en réalité différent

SolidJS uses JSX que semble identical to React’s, plus hooks-like primitives (createSignal, createEffect, createMemo). But the execution model is fundamentally différent:

  • React re-runs the whole component function quand state changements and diffs a virtual DOM to decide ce que to mettre à jour.
  • SolidJS compiles JSX to réel DOM operations at construire temps. Components run une fois; reactive signals wire valeurs directement to the spécifique DOM nodes que depend on les. Quand a signal changements, Solid updates seulement que node — aucun reconciliation, aucun virtual DOM overhead.

Ce is pourquoi SolidJS consistently sits near the top of the js-framework-benchmark suite, and pourquoi its runtime is dramatically leaner que React’s re-render model. The library itself is roughly 7KB gzipped. Plus petit, surgical updates plus a tiny runtime is the performances story — but none of que changements the rendering mode, qui is ce que decides votre SEO fate.

CSR by par défaut: the SEO problem

Construire with SolidJS alone (aucun SolidStart) and vous obtenir a client-side-rendered app:

  1. Le serveur sends index.html with a near-empty corps — typically a <div id="root"></div> and a script tag.
  2. Le navigateur downloads the JS bundle, runs Solid’s reactive code, and populates the DOM.
  3. Googlebot’s premier wave sees the vide shell — aucun content, aucun metadata.
  4. Googlebot’s second wave (the rendering queue) eventually runs the JS and sees content — but the timing is unpredictable, from hours to weeks.
  5. Bing, social robots d’exploration, and non-JS bots may jamais voir le contenu at tout.

Ce is the two-wave rendering traiter, and it’s the même trap quelconque CSR SPA falls into. The practical impacts: slow initial indexation of nouveau content; titles and meta descriptions manquant from the raw HTML (so incorrect/blank snippets in SERPs); and soft 404s, parce que a CSR app can’t retourner a vrai HTTP 404 — le serveur toujours réponses 200 with the app shell.

SolidStart: the fix

SolidStart (1,0, stable) is the official SolidJS meta-framework, construit on Vinxi (Vite + Nitro). It provides:

  • Isomorphic, file-based routing — fichiers sous src/routes/ map to URLs (src/routes/blog/[slug].tsx/blog/:slug). Un correction worth being precise à propos de: SolidStart itself ne fait pas ship a router or metadata library bundled in — per its propre docs, “SolidStart itself ne fait pas ship with a Router or Metadata library. Plutôt, it leaves que ouvrir pour vous to utiliser quelconque library vous vouloir.” The routing and @solidjs/meta behavior décrit ici come from ajout @solidjs/router and @solidjs/meta explicitly (the official templates ajouter les deux pour vous, qui is pourquoi it peut feel automatic — vérifier votre package.json plutôt que assuming ils came free with the framework).
  • Multiple rendering modes, choisi per route: CSR, SSR (synchronous, asynchronous, or streaming), and SSG / route prerendering. A SolidStart project isn’t “SSR” or “CSR” as a whole — chaque route picks its propre mode, so vérifier the rendering config (and le résultating HTML) pour the spécifique route vous care à propos de plutôt que assuming the whole site inherited un setting.
  • Server functions — a "use server" directive pour RPC-style server code (données fetching, database accès).
  • Adapters pour Cloudflare, Vercel, Netlify, Deno, Node, and static hosting.

Version remarque: ce reflects SolidStart 1,0’s current documentation, qui étiquettes itself beta and was dernier mis à jour 2026-04-28 — confirmer details contre the docs pour the version you’re en réalité running avant treating quelconque of ce as permanent API surface.

SSR vs. SSG vs. streaming — the SEO lire

  • SSR (synchronous, asynchronous, or streaming — SolidStart noms ces as distinct sub-modes) delivers complet content on the premier requête and is entièrement indexable on Wave 1. Meilleur pour frequently modification pages.
  • SSG (route prerendering) builds HTML at deploy temps — the fastest TTFB and LCP, CDN-cacheable, aucun per-request server fonctionner. Meilleur pour blogs, docs, and marketing pages. Configurer prerendered routes in app.config.ts:
// app.config.ts
import { defineConfig } from "@solidjs/start/config";

export default defineConfig({
  server: {
    prerender: {
      routes: ["/", "/about", "/blog"],
    },
  },
});
  • Streaming SSR sends HTML progressively to améliorer TTFB on data-heavy pages; Google renders the complet streamed output.
  • CSR is fine pour authenticated dashboards and outils que don’t besoin to rank — pas pour public content.

Managing head tags with @solidjs/meta

The @solidjs/meta package is the SolidJS equivalent of React Helmet or Suivant.js’s <Head>. It’s SSR-ready and asynchronous. Wrap votre app in <MetaProvider> so tags are collected during SSR, alors définir per-page tags à l’intérieur votre route components:

// src/routes/about.tsx
import { Title, Meta, Link } from "@solidjs/meta";

export default function AboutPage() {
  return (
    <>
      <Title>About Us — My Site</Title>
      <Meta name="description" content="Learn more about us." />
      <Link rel="canonical" href="https://example.com/about" />
      <Meta property="og:title" content="About Us" />
      <Meta property="og:description" content="Learn more about us." />
      <Meta property="og:image" content="https://example.com/og-about.jpg" />
      <main>...</main>
    </>
  );
}

The components disponible are <Title>, <Meta>, <Link>, <Style>, <Base>, and the <MetaProvider> wrapper. Deduplication is construit in: <Meta> tags with matching name attributes override parent definitions — the deepest (la plupart spécifique) un wins, and ce fonctionne correctement during SSR. So a root par défaut title and per-page overrides behave as you’d expect.

Un warning straight from the docs: don’t ajouter raw <title> tags in votre server fichiers — ils override @solidjs/meta’s functionality. Toujours utiliser the <Title> component, jamais a hand-written HTML title in votre serveur template.

Données structurées (JSON-LD)

Google supports JSON-LD si it’s in the raw HTML or injected by JavaScript, but SSR-rendered JSON-LD is the reliable choice. In SolidStart, render it in the route component:

export default function ArticlePage() {
  const schema = {
    "@context": "https://schema.org",
    "@type": "Article",
    "headline": "My Article",
    "author": { "@type": "Person", "name": "Author Name" },
  };

  return (
    <>
      <script
        type="application/ld+json"
        innerHTML={JSON.stringify(schema)}
      />
      <article>...</article>
    </>
  );
}

With SSR enabled, the JSON-LD apparaît in le serveur-rendered HTML — the preferred approach pour reliability à travers every robot d’exploration. Validate with the Résultats enrichis Tester or Inspection d’URL Outil.

Hydration, pas resumability — the accuracy spine

Hydration is the traiter où, après SSR delivers rendered HTML, the framework attaches to the existing DOM to faire it interactive: download the JS bundle, execute the framework code, reconcile state with the existing nodes, attach event listeners. SolidJS uses hydration — the même fundamental mechanism as React’s hydrate, Vue’s createSSRApp, or Angular SSR.

Resumability (Qwik’s architecture) is différent: le serveur serializes the framework’s execution state into the HTML, and the client resumes from là sans re-executing components — interactive avant quelconque JS runs.

The myth to debunk: SolidJS’s fine-grained reactivity is parfois confused with resumability parce que les deux éviter “re-running” components in the traditional sense. Ils ne sont pas the même chose. Fine-grained reactivity is a client-side mettre à jour optimization; resumability is a server-to-client startup mechanism. SolidJS encore downloads and runs its runtime avant lune page is interactive.

The SEO implication: les deux SSR+hydration (SolidJS) and resumability (Qwik) put rendered HTML in le serveur réponse, so les deux are bon pour indexation. The difference is Temps d’interactivité and INP on slow devices, où Qwik’s near-zero startup JS has the edge. Pour explorer and index, SolidStart SSR is déjà suffisant.

Core Web Vitals

SolidJS’s runtime advantages peut translate into meilleur Core Web Vitals scores on routes que utiliser SSR — but ce isn’t automatic or universal. Aucun principal source establishes guaranteed cheap hydration or meilleur outcomes pour every Solid/SolidStart route: bundle size, données fetching, third-party scripts, device, and the route’s réel rendering mode tout determine the réel cost. Treat the suivant as the mechanism by qui SolidJS peut aider, and mesurer votre propre routes to confirmer it fait:

  • LCP improves parce que the largest content element is in le serveur-rendered HTML — aucun waiting on JS.
  • INP improves parce que Solid’s fine-grained runtime handles interactions efficiently (aucun virtual DOM diffing).
  • CLS drops parce que SSR’d content doesn’t shift as late-loading JS fills in.

A caution worth keeping honest: figures comme “SolidJS is ~70% faster que React’s virtual DOM” come from synthetic benchmarks (js-framework-benchmark), pas real-world field données. Réel CWV dépend far plus on implementation quality, données fetching, and hosting que on framework choice. Treat the benchmark numbers as directional, and mesurer votre propre field données in CrUX / Search Console.

Routing, données fetching, and réel 404s

Routing. SolidStart uses the History API by par défaut — jamais utiliser hash-based (#/page) routing, qui empêche reliable URL discovery. Garder trailing-slash behavior consistent and enforce it with server redirections, pas simplement canonicals.

Données fetching pour le SEO. Content que nécessite to rank doit be chargé on the server so it’s in the SSR HTML. Utiliser createAsync and server functions — pas onMount or client-side effects, qui run après the HTML is sent:

// Server-side data fetch — content lands in the initial HTML ✓
import { createAsync } from "@solidjs/router";
import { getPost } from "~/lib/api";

export const route = {
  load: ({ params }) => getPost(params.slug),
};

export default function BlogPost(props) {
  const post = createAsync(() => getPost(props.params.slug));
  return <article>{post()?.content}</article>;
}

Réel 404s. A catch-all route plus <HttpStatusCode> from @solidjs/start sets the réel HTTP réponse code on le serveur — a vrai 404 au lieu de a soft 404:

// src/routes/[...404].tsx
import { HttpStatusCode } from "@solidjs/start";

export default function NotFound() {
  return (
    <>
      <HttpStatusCode code={404} />
      <h1>Page Not Found</h1>
    </>
  );
}

Sitemaps, robots.txt, and international SEO

  • robots.txt — ajouter public/robots.txt at the project root and point it at votre sitemap. Don’t block the /api/ routes utilisé pour XHR données fetching.
  • Sitemap — the third-party solid-start-sitemap plugin (by madaxen86) generates sitemap.xml at construire temps and supports dynamic routes via parameter mapping or a runtime API route.
  • International SEO — emit hreflang with <Link rel="alternate" hreflang="…"> from @solidjs/meta, and utiliser a subdirectory structure (/en/, /fr/) over subdomains or requête parameters.

Courant SolidJS SEO pitfalls

  1. Running SolidJS CSR sans SolidStart SSR/SSG.
  2. Fetching rankable content in onMount / client-side effects.
  3. Forgetting the <MetaProvider> wrapper (tags won’t render in SSR).
  4. Ajout raw <title> HTML tags in server templates (overrides @solidjs/meta).
  5. En utilisant hash-based routing.
  6. Serving soft 404s sans <HttpStatusCode>.
  7. Blocking API routes in robots.txt.
  8. Pas fingerprinting JS assets (Google caches scripts aggressively).
  9. Content behind a click/accordion/tab que jamais auto-loads into the DOM.
  10. Assuming SSR fonctionne sans verifying via View Source / Inspection d’URL.
  11. Assuming @solidjs/router and @solidjs/meta come bundled with SolidStart — ils don’t; SolidStart’s propre docs dire it “ne fait pas ship with a Router or Metadata library.” Official templates ajouter les deux pour vous, but a from-scratch or customized setup nécessite les installed explicitly.
  12. Treating a project as uniformly “SSR” or “CSR” — rendering mode is définir per route in SolidStart, so a route vous assume is server-rendered may pas be.

Où ce sits

SolidJS lives in the JavaScript frameworks subcluster alongside Qwik, sous the broader JavaScript SEO cluster. Pour the closest parallel, voir React SEO — SolidJS shares React’s JSX and CSR-by-default problem, but fixes it with SolidStart au lieu de Suivant.js, and runs faster thanks to aucun virtual DOM. Pour how Google sees rendered content, voir rendering and exploration.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.