12k
All articles

Rendu côté serveur dans Solid avec SolidStart

Créez une application SolidStart v2 avec données rendues côté serveur, query et createAsync, préchargement des routes, fonctions serveur et déploiement.

OpenReplay Team
OpenReplay Team
Rendu côté serveur dans Solid avec SolidStart

SolidStart v2 (@solidjs/start 2.x) · Solid v1 · Node.js 24+ · Vite 8

SolidStart est le framework full-stack de SolidJS. Il ajoute aux composants Solid le routage basé sur les fichiers, le rendu côté serveur et les fonctions serveur. Il joue pour Solid le rôle que Next.js joue pour React et SvelteKit pour Svelte.

Si vous écrivez déjà des composants Solid, la vraie difficulté pour passer au full-stack, ce sont les tutoriels. La plupart utilisent encore app.config.ts et Vinxi, qui n’existent ni l’un ni l’autre dans la version majeure actuelle. Cet article construit une petite application SolidStart v2 avec des données chargées côté serveur et une page de détail avec préchargement. Il aborde ensuite les fonctions serveur, la configuration du rendu, le déploiement, et la question de savoir si l’écosystème est assez mature pour être préféré à une stack React. Il suppose que vous maîtrisez les patterns au niveau des composants présentés dans les bonnes pratiques SolidJS.

Points clés

  • SolidStart v2 est devenu stable le 4 août 2026. Il cible Solid v1, remplace Vinxi par l’Environment API de Vite, nécessite Node.js 24+ et Vite 8, et se configure dans vite.config.ts.
  • Dans SolidStart v2, les données de route se chargent en enveloppant une fonction asynchrone dans query de @solidjs/router, puis en la lisant avec createAsync.
  • Une directive "use server" placée en tête du corps d’une query exécute cette fonction côté serveur, où elle peut accéder aux secrets et aux données de session.
  • Exporter route.preload depuis un module de route lance la query de la route avant le rendu du composant de page.
  • SolidStart v2 se déploie via des plugins Vite (Nitro v3, Cloudflare, Netlify) et ne maintient pas ses propres adaptateurs d’hébergement.

Qu’est-ce que SolidStart et où en est la v2 ?

SolidStart est la couche méta-framework au-dessus de Solid. Solid effectue le rendu des composants. SolidStart ajoute autour d’eux le routage, le rendu côté serveur, le chargement des données et une chaîne de build et de déploiement.

SolidStart v2 est passé en version stable le 4 août 2026. Vinxi a disparu : la v2 s’appuie désormais sur l’Environment API de Vite. Il vous faut Node.js 24 ou supérieur ainsi que Vite 8, et la configuration du framework se trouve maintenant dans vite.config.ts et non plus dans app.config.ts. La v2 est conçue pour Solid v1. L’annonce de la Release Candidate de Solid 2.0 précise que SolidStart ne reçoit désormais plus que des versions de maintenance, et que dans Solid 2.0, un mode Start intégré au cœur de Solid reprend son rôle. Les applications déjà en production sous SolidStart continuent de fonctionner. Le code ci-dessous cible Solid v1 et SolidStart v2. Si vous mettez à niveau une application v1 existante, suivez le guide de migration depuis la v1.

Créer un projet SolidStart

Pour générer la structure d’un projet, lancez l’initialiseur Solid et choisissez le template SolidStart lorsque l’invite vous le demande :

npm init solid
# or: pnpm create solid
cd my-app
npm install

L’application se configure dans vite.config.ts. La configuration minimale présentée dans le guide de démarrage ressemble à ceci :

import { defineConfig } from "vite";
import { solidStart } from "@solidjs/start/config";

export default defineConfig({
  plugins: [solidStart()],
});

En production, on associe solidStart() à un plugin serveur, par exemple Nitro v3. La référence de configuration de solidStart tient les paramètres Nitro à l’écart de solidStart() : ils se placent dans une clé nitro distincte, au niveau racine.

Chaque fichier situé sous src/routes devient soit une page, soit un endpoint d’API. La page de la v2 consacrée aux routes d’API explique que les endpoints suivent les mêmes règles de correspondance fichier-chemin que les pages. Un alias intégré ~ pointe vers la racine de l’application : avec les paramètres par défaut, ~/lib/db correspond donc à src/lib/db.

Charger les données côté serveur avec query et createAsync

Dans SolidStart, les données de route proviennent d’une fonction asynchrone enveloppée dans query de @solidjs/router. Un composant les lit ensuite via createAsync. C’est le pattern utilisé dans la documentation de la v2 sur la récupération des données. Cette documentation indique également que SolidStart v2 fonctionne avec Solid Router v1 ou TanStack Solid Router v1. Les exemples présentés ici utilisent Solid Router.

Commencez par un module de données dans src/lib/posts.ts. Il utilise un tableau en mémoire afin que l’exemple fonctionne sans base de données :

export type Post = { id: string; title: string; body: string };

const posts: Post[] = [
  { id: "1", title: "Hello SolidStart", body: "First post." },
  { id: "2", title: "Server functions", body: "Second post." },
];

export async function listPosts() {
  return posts.map(({ id, title }) => ({ id, title }));
}

export async function findPost(id: string) {
  return posts.find((p) => p.id === id) ?? null;
}

La route de la liste des articles :

import { For } from "solid-js";
import { createAsync, query, type RouteDefinition } from "@solidjs/router";
import { listPosts } from "~/lib/posts";

const getPostList = query(async () => {
  "use server";
  return listPosts();
}, "post-list");

export const route = {
  preload: () => getPostList(),
} satisfies RouteDefinition;

export default function PostsPage() {
  const list = createAsync(() => getPostList());
  return (
    <ul>
      <For each={list()}>
        {(post) => (
          <li>
            <a href={`/posts/${post.id}`}>{post.title}</a>
          </li>
        )}
      </For>
    </ul>
  );
}

La page de détail est une route dynamique qui reçoit un paramètre id. La documentation de la v2 sur le routage décrit la syntaxe des noms de fichiers pour les segments dynamiques.

import { Show } from "solid-js";
import { createAsync, query, type RouteDefinition } from "@solidjs/router";
import { findPost } from "~/lib/posts";

const getPostById = query(async (id: string) => {
  "use server";
  return findPost(id);
}, "post-by-id");

export const route = {
  preload: ({ params }) => getPostById(params.id),
} satisfies RouteDefinition;

export default function PostPage(props: { params: { id: string } }) {
  const post = createAsync(() => getPostById(props.params.id));
  return (
    <Show when={post()} fallback={<p>Post not found.</p>}>
      {(p) => (
        <article>
          <h1>{p().title}</h1>
          <p>{p().body}</p>
        </article>
      )}
    </Show>
  );
}

Le second argument de query est la clé de cache : attribuez donc à chaque query sa propre clé. L’export route.preload lance la query avant le rendu du composant de page, ce qui signifie que le chargement des données démarre en même temps que la navigation.

Formulaires, mutations et revalidation

Renvoyer des données vers le serveur ne fonctionne pas comme leur lecture. Une mutation doit modifier l’état côté serveur, puis signaler à la page que ses lectures en cache sont obsolètes. Dans la v2, les écritures passent par l’action de Solid Router, avec une directive "use server" dans le corps de l’action lorsque le traitement doit s’effectuer côté serveur. La page de la v2 sur la mutation des données présente les exemples de formulaires à jour, la gestion des états en attente et d’erreur, ainsi que le passage d’arguments supplémentaires avec .with().

Côté lecture, la revalidation reprend les éléments de la section précédente. Chaque query est mise en cache sous sa clé ("post-list" et "post-by-id" ci-dessus), et createAsync relit les données lorsque l’entrée correspondante est revalidée. Lorsqu’une action réussit, Solid Router revalide par défaut toutes les queries actives de la page. Pour n’en rafraîchir que certaines, passez des clés à revalidate : getPostList.key cible toutes les instances d’une query, et getPostById.keyFor(id) en cible une seule. La documentation sur la récupération des données délègue le comportement du cache à Solid Router, dont la page sur la revalidation l’explique en détail.

Des noms de clés de query clairs et stables sont payants lorsque vous affinez la revalidation. Une mutation qui ajoute un article n’a besoin de rafraîchir que "post-list", tandis qu’une modification doit aussi rafraîchir "post-by-id".

À quoi sert “use server” ?

Placer la directive "use server" en tête du corps d’une fonction fait exécuter cette fonction côté serveur, même lorsqu’elle est appelée depuis un composant. C’est pourquoi une query ainsi marquée peut lire les secrets de process.env et les données de session. La documentation de la v2 sur la récupération des données l’illustre avec useSession de @solidjs/start/http dans son exemple exécuté uniquement côté serveur.

À placer dans "use server"À garder en dehors
Secrets d’environnement (process.env.*)API du navigateur (window, localStorage, DOM)
Accès à la base de données et à la sessionÉtat d’UI propre aux composants
Helpers de @solidjs/start/httpTout ce qui doit s’exécuter au clic sans requête

Dans une application SolidStart, l’état de l’interface relève du client. Le serveur détient les données, tandis que les signaux et les stores gèrent l’état d’interaction, une répartition détaillée dans la gestion d’état dans SolidJS.

SolidStart v2 reconnaît également les imports marqueurs server-only et client-only. Ajoutez-en un à un module : l’importer du mauvais côté (du code serveur dans le client, ou l’inverse) fera échouer le serveur de développement ou le build, si bien que l’erreur n’atteint jamais les utilisateurs. La référence de configuration indique que @solidjs/start/http et @solidjs/start/middleware sont déjà marqués server-only. En développement, vous disposez aussi d’une barre d’outils qui affiche les erreurs de l’application et les appels aux fonctions serveur. Elle n’est jamais incluse dans un build de production.

Les modes de rendu dans SolidStart

Dans SolidStart v2, le comportement du rendu se configure via le plugin solidStart() et le plugin de déploiement qui lui est associé, tous deux déclarés dans vite.config.ts. Pour les compromis conceptuels entre rendu côté serveur, streaming et génération statique, consultez les 10 principaux patterns de rendu. Cette section se limite à indiquer où ces choix se font dans SolidStart.

Puisque app.config.ts n’existe plus, les options de rendu de l’époque v1 que vous trouverez dans d’anciens articles ne s’appliquent pas telles quelles. Pour connaître les options exposées par la v2, consultez la référence de configuration de solidStart() et la documentation des plugins de déploiement.

Lorsqu’une page est rendue côté serveur, les utilisateurs voient le balisage avant que le JavaScript client ne l’ait hydraté. Les replays de session d’applications SSR rendent ce décalage visible : un utilisateur appuie sur un bouton qui s’affiche correctement mais ne réagit pas, puis appuie de nouveau une fois les gestionnaires d’événements attachés.

Déployer SolidStart v2

SolidStart v2 ne dispose pas de ses propres adaptateurs d’hébergement. Il se déploie via des plugins Vite, et l’annonce de la v2 cite trois cibles prises en charge : le plugin Vite Nitro v3 (encore en bêta selon cette annonce), le plugin Vite Cloudflare et le plugin Vite Netlify. Le guide de démarrage renvoie vers une page consacrée aux plugins de déploiement, qui détaille la configuration du runtime de production pour chacun d’eux.

L’écosystème est le véritable coût du choix de SolidStart plutôt que d’une stack React. React offre bien plus de bibliothèques de composants tierces, d’intégrations d’authentification et de templates d’hébergement, et les équipes Solid écrivent elles-mêmes une plus grande part de ce code d’intégration. La comparaison SolidJS vs React met cet écart en regard du modèle de rendu de Solid. Gardez également à l’esprit que SolidStart v2 est en maintenance pendant que Solid 2.0 évolue vers le mode Start.

Conclusion

SolidStart v2 est une solution stable et native Vite pour ajouter le rendu côté serveur aux applications Solid v1. Le chargement des données repose sur trois éléments : query, createAsync et une directive "use server", complétés par route.preload pour une récupération anticipée. L’étape suivante consiste à générer un projet avec npm init solid, à ajouter les deux routes d’articles présentées ci-dessus, puis à mettre en place une mutation en vous appuyant sur la section de la documentation v2 consacrée à la mutation des données.

FAQ

SolidStart v2 fonctionne-t-il avec Solid 2.0 ?

Non. SolidStart v2 est conçu pour Solid 1.x, et aucune version de SolidStart ne cible Solid 2.0. La Release Candidate de Solid 2.0 met SolidStart à la retraite et répartit ses composantes ailleurs : le cœur de Solid gère désormais les fonctions serveur, le mode Start se charge du service, et un package distinct, indépendant du routeur, prend en charge le routage basé sur le système de fichiers. Les applications SolidStart existantes continuent de fonctionner, SolidStart reçoit toujours des versions de maintenance, et un guide de migration officiel accompagne le passage au mode Start.

Quelle est la différence entre TanStack Start et SolidStart avec TanStack Router ?

Ce sont deux options distinctes. SolidStart v2 est indépendant du routeur et fonctionne avec le Solid Router v1 officiel ou avec TanStack Solid Router v1 : vous pouvez donc utiliser le routage TanStack sans quitter SolidStart. TanStack Start est un méta-framework distinct doté d'une variante Solid, publiée sous le nom @tanstack/solid-start, qui dispose déjà d'une version bêta pour Solid 2.0. Pour Solid 2.0, le starter fullstack-tanstack combine le mode Start avec TanStack Router et TanStack Query.

Que sont les single-flight mutations dans SolidStart ?

Les single-flight mutations renvoient les données mises à jour dans la même réponse serveur que la mutation elle-même. Lorsqu'une action côté serveur modifie des données préchargées par la vue courante, ou redirige vers une page dont les données sont préchargées, SolidStart revalide ces données côté serveur et les livre dans le même aller-retour. Le client n'a pas à émettre une seconde série de requêtes : il n'y a donc pas de cascade de requêtes après une écriture.

Qu'est-ce qui change lors de la mise à niveau d'une application SolidStart v1 vers la v2 ?

La mise à niveau nécessite Node.js 24 et Vite 8. La configuration du framework passe de app.config.ts à vite.config.ts, où solidStart() est enregistré en tant que plugin Vite, et l'Environment API de Vite remplace Vinxi. Le guide de migration officiel détaille également les changements concernant les chemins d'import, les types d'environnement TypeScript, le runtime serveur et les middlewares. Vérifiez les chemins d'import et le code des middlewares de la v1 à l'aide du guide plutôt que de les reprendre tels quels.

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.