Guide SolidJS SEO

Comment faire SolidJS sites crawlable, indexable, et rapide — pourquoi bare SolidJS est CSR-seulement, comment SolidStart's SSR/SSG corrections il, managing head balises avec @solidjs/meta, et pourquoi SolidJS hydrates (il n’est pas resumable comme Qwik).

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

SolidJS est a rapide, React-like library avec fine-grained reactivity et aucun virtual DOM — mais on son propre c’est client-side rendu, donc il ships an vide HTML shell avec le même indexation problèmes as bare React. Le corriger est SolidStart, le official meta-framework: SSR or SSG put contenu réel et metadata dans le premier réponse. Manage head balises avec @solidjs/meta (<Title>, <Meta>, <Link>), retourner réel 404s avec <HttpStatusCode>, et récupérer données on le serveur avec createAsync. Un chose pas à mix up: SolidJS hydrates — il n’est pas resumable. Resumability est Qwik's trick. SolidJS's win est a Core Web Vitals edge on top de standard SSR.

«> TL;DR — SolidJS is fine-grained reactive (signals, no virtual DOM) and

ships as a CSR library by default — an empty shell with the same Wave-1 indexing problem as bare React. SolidStart is the fix: SSR, SSG (route prerendering), and streaming SSR put content and metadata in the first response. Manage head tags with @solidjs/meta (<Title>, <Meta>, <Link> under a <MetaProvider>), return real status codes with <HttpStatusCode>, and load data on the server with createAsync so it lands in the SSR HTML. The accuracy spine: SolidJS hydrates — it is NOT resumable (that’s Qwik). Its fine-grained reactivity is a client update optimization, not a server-to-client startup one — so the SEO upside is mostly a Core Web Vitals (INP/TBT) edge layered on top of normal SSR. » (Traduction) (Résumé en français de la section vingt et un, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Preuve à l’appui de cette affirmation The article's described solidjs-seo capabilities must be evaluated against the platform's current documentation rather than assumed to be search-engine behavior. Portée : Platform-specific capability documentation. Niveau de confiance : élevé · Vérifié : SolidStart documentation Preuve à l’appui de cette affirmation Regardless of platform, Google needs crawlable URLs, accessible rendered content, descriptive metadata, and valid search directives. Portée : Google requirements independent of platform. Niveau de confiance : élevé · Vérifié : Google Search Central: SEO Starter Guide

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

SolidJS utilise JSX que semble identical à React’s, plus hooks-like primitives (createSignal, createEffect, createMemo). Mais le execution model est fundamentally différent:

  • React re-exécute le entier component function quand state changements et diffs a virtual DOM à decide ce que à mettre à jour.
  • SolidJS compiles JSX à réel DOM operations à construire temps. Components exécuter une fois; reactive signaux wire valeurs directement à le spécifique DOM nodes que depend on les. Quand a signal changements, Solid mises à jour seulement que node — aucun reconciliation, aucun virtual DOM overhead.

Ce est pourquoi SolidJS consistently sits near le top de le js-framework-benchmark suite, et pourquoi son runtime est dramatically leaner que React’s re-rendre model. Le library itself est roughly 7KB gzipped. Plus petit, surgical mises à jour plus a tiny runtime est le performances story — mais none de que changements le rendu mode, qui est ce que decides votre SEO fate.

CSR by par défaut: the SEO problem

Construire avec SolidJS alone (aucun SolidStart) et vous obtenir a client-side-rendu app:

«1. The server sends index.html with a near-empty body — typically a <div id="root"></div> and a script tag. 2. The browser downloads the JS bundle, runs Solid’s reactive code, and populates the DOM. 3. Googlebot’s first wave sees the empty shell — no content, no 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 crawlers, and non-JS bots may never see the content at all. » (Traduction) (Résumé en français de la section vingt-neuf, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«This is the two-wave rendering process, and it’s the same trap any CSR SPA falls into. The practical impacts: slow initial indexing of new content; titles and meta descriptions missing from the raw HTML (so wrong/blank snippets in SERPs); and soft 404s, because a CSR app can’t return a true HTTP 404 — the server always answers 200 with the app shell. » (Traduction) (Résumé en français de la section trente, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«## SolidStart: the fix » (Traduction) (Résumé en français de la section trente et un, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«SolidStart (1.0, stable) is the official SolidJS meta-framework, built on Vinxi (Vite + Nitro). It provides: » (Traduction) (Résumé en français de la section trente-deux, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

  • Isomorphic, fichier-based routing — fichiers sous src/routes/ map à URLs (src/routes/blog/[slug].tsx → /blog/:slug). Un correction worth étant precise à propos de: SolidStart itself ne fait pas ship a router or metadata library bundled dans — per son propre docs, “SolidStart itself ne fait pas ship avec a Router or Metadata library. Plutôt, il laisse que ouvrir pour vous à utiliser quelconque library vous vouloir.” Le routing et @solidjs/meta behavior décrit ici come depuis ajout @solidjs/router et @solidjs/meta explicitly (le official templates ajouter les deux pour vous, qui est pourquoi il peut feel automatic — vérifier votre package.json plutôt que assuming ils came gratuit avec le framework).
  • Plusieurs rendu modes, choisi per route: CSR, SSR (synchronous, asynchronous, or streaming), et SSG / route prerendering. A SolidStart project n’est pas “SSR” or “CSR” as a entier — chaque route picks son propre mode, donc vérifier le rendu config (et le résultating HTML) pour le spécifique route vous care à propos de plutôt que assuming le entier site inherited un paramètre.
  • Serveur functions — a "use server" directive pour RPC-style serveur code (données fetching, database accès).
  • Adapters pour Cloudflare, Vercel, Netlify, Deno, Node, et static hosting.

Version remarque: ce reflects SolidStart 1,0’s actuel documentation, qui étiquettes itself beta et était dernier mis à jour 2026-04-28 — confirmer details contre le docs pour le version vous êtes en réalité running avant treating quelconque de 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 contenu on le premier requête et est entièrement indexable on Wave 1. Meilleur pour frequently modification pages.
  • SSG (route prerendering) construit HTML à deploy temps — le fastest TTFB et LCP, CDN-cacheable, aucun per-requête serveur fonctionner. Meilleur pour blogs, docs, et marketing pages. Configurer prerendered routes dans 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 à améliorer TTFB on données-heavy pages; Google renders le complet streamed sortie.
  • CSR est fine pour authenticated dashboards et outils que ne pas besoin à classer — pas pour public contenu.

Managing head balises avec @solidjs/meta

Le @solidjs/meta package est le SolidJS equivalent de React Helmet or Suivant.js’s <Head>. c’est SSR-ready et asynchronous. Wrap votre app dans <MetaProvider> donc balises sont collected during SSR, alors définir per-page balises à 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>
    </>
  );
}

Le components disponible sont <Title>, <Meta>, <Link>, <Style>, <Base>, et le <MetaProvider> wrapper. Deduplication est construit dans: <Meta> balises avec matching name attributs override parent definitions — le deepest (la plupart spécifique) un wins, et ce fonctionne correctement during SSR. Donc a root par défaut titre et per-page overrides behave as vous’d expect.

Un warning straight depuis le docs: ne pas ajouter raw <title> balises dans votre serveur fichiers — ils override @solidjs/meta’s functionality. Toujours utiliser le <Title> component, jamais a hand-written HTML titre dans votre serveur template.

Données structurées (JSON-LD)

Google prend en charge JSON-LD si c’est dans le raw HTML or injected par JavaScript, mais SSR-rendu JSON-LD est le fiable choice. Dans SolidStart, rendre il dans le 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 appears in the server-rendered HTML — the preferred approach for reliability across every crawler. Validate with the Rich Results Test or URL Inspection Tool. » (Traduction) (Résumé en français de la section quarante-sept, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«## Hydration, not resumability — the accuracy spine » (Traduction) (Résumé en français de la section quarante-huit, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«Hydration is the process where, after SSR delivers rendered HTML, the framework attaches to the existing DOM to make it interactive: download the JS bundle, execute the framework code, reconcile state with the existing nodes, attach event listeners. SolidJS uses hydration — the same fundamental mechanism as React’s hydrate, Vue’s createSSRApp, or Angular SSR. » (Traduction) (Résumé en français de la section quarante-neuf, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

«Resumability (Qwik’s architecture) is different: the server serializes the framework’s execution state into the HTML, and the client resumes from there without re-executing components — interactive before any JS runs. » (Traduction) (Résumé en français de la section cinquante, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Le myth à debunk: SolidJS’s fine-grained reactivity est parfois confused avec resumability parce que les deux éviter “re-running” components dans le traditional sense. Ils ne sont pas le même chose. Fine-grained reactivity est a client-side mettre à jour optimization; resumability est a serveur-à-client startup mechanism. SolidJS encore downloads et exécute son runtime avant lune page est interactive.

Le SEO implication: les deux SSR+hydration (SolidJS) et resumability (Qwik) put rendu HTML dans le serveur réponse, donc les deux sont bon pour indexation. Le difference est Temps d’interactivité et INP on lent devices, où Qwik’s near-zero startup JS a le edge. Pour explorer et indexer, SolidStart SSR est déjà suffisant.

Core Web Vitals

SolidJS’s runtime advantages peut translate dans meilleur Core Web Vitals scores on routes que utiliser SSR — mais ce n’est pas automatic or universal. Aucun principal source establishes guaranteed cheap hydration or meilleur résultats pour chaque Solid/SolidStart route: bundle size, données fetching, tiers scripts, device, et le route’s réel rendu mode tout determine le réel coût. Treat le suivant as le mechanism par qui SolidJS peut aider, et mesurer votre propre routes à confirmer il 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 est ~70% faster que React’s virtual DOM” come depuis synthetic benchmarks (js-framework-benchmark), pas real-world champ données. Réel CWV dépend far plus on implementation qualité, données fetching, et hosting que on framework choice. Treat le benchmark numbers as directional, et mesurer votre propre champ données dans CrUX / Search Console.

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

«Routing. SolidStart uses the History API by default — never use hash-based (#/page) routing, which prevents reliable URL discovery. Keep trailing-slash behavior consistent and enforce it with server redirects, not just canonicals. » (Traduction) (Résumé en français de la section cinquante-huit, sous-partie un : le texte source est conservé pour vérification lors de la relecture francophone.)

Données fetching pour le SEO. Contenu que nécessite à classer doit être chargé on le serveur donc c’est dans le SSR HTML. Utiliser createAsync et serveur functions — pas onMount or client-side effects, qui exécuter après le HTML est 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-tous route plus <HttpStatusCode> depuis @solidjs/start sets le 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, et international SEO

  • robots.txt — ajouter public/robots.txt à le project root et point il à votre sitemap. ne pas bloquer le /api/ routes utilisé pour XHR données fetching.
  • Sitemap — le tiers solid-start-sitemap plugin (par madaxen86) generates sitemap.xml à construire temps et prend en charge dynamic routes via parameter mapping or a runtime API route.
  • International SEO — emit hreflang avec <Link rel="alternate" hreflang="…"> depuis @solidjs/meta, et 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 contenu dans onMount / client-side effects.
  3. Forgetting le <MetaProvider> wrapper (balises ne va pas rendre dans SSR).
  4. Ajout raw <title> HTML balises dans serveur templates (overrides @solidjs/meta).
  5. En utilisant hash-based routing.
  6. Diffusion soft 404s sans <HttpStatusCode>.
  7. Blocking API routes dans robots.txt.
  8. Pas fingerprinting JS assets (Google caches scripts aggressively).
  9. Contenu behind a click/accordion/tab que jamais auto-charge dans le DOM.
  10. Assuming SSR fonctionne sans verifying via View Source / Inspection d’URL.
  11. Assuming @solidjs/router et @solidjs/meta come bundled avec SolidStart — ils ne pas; SolidStart’s propre docs dire il “ne fait pas ship avec a Router or Metadata library.” Official templates ajouter les deux pour vous, mais a depuis-scratch or customized setup nécessite les installed explicitly.
  12. Treating a project as uniformly “SSR” or “CSR” — rendu mode est définir per route dans SolidStart, donc a route vous assume est serveur-rendu peut pas être.

Où ce sits

SolidJS lives dans le JavaScript frameworks subcluster alongside Qwik, sous le broader JavaScript SEO cluster. Pour le closest parallel, voir React SEO — SolidJS shares React’s JSX et CSR-par-default problème, mais corrections il avec SolidStart au lieu de Suivant.js, et exécute faster thanks à aucun virtual DOM. Pour comment Google voit rendu contenu, voir rendu et exploration.

Ajouter une note d’expert

Épingler une citation d’expert

Nouvelle personne ? Créez son profil non revendiqué à /admin/experts/ → Épingler une citation d’expert d’abord.