Renderização no servidor no Solid com SolidStart
Crie um app SolidStart v2 com dados renderizados no servidor, query e createAsync, pré-carregamento de rotas, funções de servidor e implantação.
SolidStart v2 (@solidjs/start 2.x) · Solid v1 · Node.js 24+ · Vite 8
SolidStart é o framework full-stack do SolidJS. Ele adiciona roteamento baseado em arquivos, renderização no servidor e server functions aos componentes Solid, cumprindo o papel que o Next.js desempenha para o React e o SvelteKit para o Svelte.
Se você já escreve componentes Solid, a parte difícil de migrar para o full-stack são os tutoriais. A maioria ainda usa app.config.ts e Vinxi, e nenhum dos dois existe na versão major atual. Este artigo constrói uma pequena aplicação SolidStart v2 com dados carregados no servidor e uma página de detalhes com preload. Em seguida, aborda server functions, configuração de renderização, deploy e se o ecossistema está maduro o suficiente para ser escolhido no lugar de uma stack React. Parte-se do princípio de que você conhece os padrões em nível de componente abordados em boas práticas de SolidJS.
Principais conclusões
- O SolidStart v2 se tornou estável em 4 de agosto de 2026. Ele é voltado para o Solid v1, substitui o Vinxi pela Environment API do Vite, exige Node.js 24+ e Vite 8 e é configurado em
vite.config.ts. - No SolidStart v2, os dados de rota são carregados envolvendo uma função assíncrona em
queryde@solidjs/routere lendo-a comcreateAsync. - Uma diretiva
"use server"no início do corpo de uma query faz com que essa função seja executada no servidor, onde ela pode ler segredos e dados de sessão. - Exportar
route.preloadde um módulo de rota inicia a query da rota antes de o componente da página ser renderizado. - O SolidStart v2 faz deploy por meio de plugins do Vite (Nitro v3, Cloudflare, Netlify) e não mantém adaptadores de hospedagem próprios.
O que é o SolidStart e em que pé está a v2?
O SolidStart é a camada de meta-framework sobre o Solid. O Solid renderiza componentes. O SolidStart adiciona roteamento, renderização no servidor, carregamento de dados e um pipeline de build e deploy em torno deles.
O SolidStart v2 se tornou estável em 4 de agosto de 2026. O Vinxi foi removido, e a v2 passou a ser construída sobre a Environment API do Vite. Você precisa do Node.js 24 ou superior e do Vite 8, e as configurações do framework agora ficam em vite.config.ts, e não mais em app.config.ts. A v2 foi feita para o Solid v1. O anúncio do Release Candidate do Solid 2.0 informa que o SolidStart agora recebe apenas releases de manutenção e que, no Solid 2.0, um modo Start embutido no núcleo do Solid assume esse papel. Aplicações que já rodam SolidStart em produção continuam funcionando. O código a seguir é voltado para o Solid v1 e o SolidStart v2. Se você estiver atualizando uma aplicação v1 existente, siga o guia de migração da v1.
Crie um projeto SolidStart
Para criar a estrutura de um projeto, execute o inicializador do Solid e escolha o template SolidStart quando solicitado:
npm init solid
# or: pnpm create solid
cd my-app
npm install
A aplicação é configurada em vite.config.ts. A configuração mínima do guia de primeiros passos é esta:
import { defineConfig } from "vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
plugins: [solidStart()],
});
Em produção, você combina solidStart() com um plugin de servidor, como o Nitro v3. A referência de configuração do solidStart mantém as configurações do Nitro fora de solidStart(): elas ficam em uma chave nitro separada, no nível superior.
Cada arquivo em src/routes se torna uma página ou um endpoint de API. A página de rotas de API da v2 explica que os endpoints seguem as mesmas regras de mapeamento de arquivo para caminho que as páginas. Um alias ~ embutido aponta para a raiz da aplicação, de modo que, com as configurações padrão, ~/lib/db corresponde a src/lib/db.
Carregue dados no servidor com query e createAsync
No SolidStart, os dados de rota vêm de uma função assíncrona envolvida em query de @solidjs/router. Um componente então os lê por meio de createAsync. Esse é o padrão usado na documentação de data fetching da v2. A documentação também informa que o SolidStart v2 funciona com o Solid Router v1 ou o TanStack Solid Router v1. Os exemplos aqui usam o Solid Router.
Comece com um módulo de dados em src/lib/posts.ts. Ele usa um array em memória para que o exemplo rode sem banco de dados:
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;
}
A rota da lista de posts:
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>
);
}
A página de detalhes é uma rota dinâmica que recebe um parâmetro id. A documentação de roteamento da v2 explica a sintaxe de nomes de arquivo para segmentos dinâmicos.
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>
);
}
O segundo argumento de query é a chave de cache, portanto dê a cada query uma chave própria. O export route.preload inicia a query antes de o componente da página ser renderizado, o que significa que o carregamento dos dados começa no mesmo instante que a navegação.
Formulários, mutations e revalidação
Gravar dados no servidor funciona de forma diferente de lê-los. Uma mutation precisa alterar o estado no servidor e depois avisar a página de que suas leituras em cache estão desatualizadas. Na v2, as gravações passam pela action do Solid Router, com uma diretiva "use server" dentro do corpo da action quando o trabalho precisa acontecer no servidor. A página de mutação de dados da v2 traz os exemplos atuais de formulários, estados pendente e de erro e a passagem de argumentos extras com .with().
O lado de leitura da revalidação vem da seção anterior. Cada query é armazenada em cache sob sua chave ("post-list" e "post-by-id" acima), e createAsync faz uma nova leitura quando essa entrada em cache é revalidada. Quando uma action é concluída com sucesso, o Solid Router, por padrão, revalida todas as queries ativas na página. Para atualizar apenas algumas delas, passe chaves para revalidate: getPostList.key atinge todas as instâncias de uma query, e getPostById.keyFor(id) atinge uma específica. A documentação de data fetching delega o comportamento de cache ao Solid Router, e a página de revalidação do router o explica em detalhes.
Nomes de chave de query claros e estáveis compensam quando você restringe a revalidação. Uma mutation que adiciona um post só precisa atualizar "post-list", enquanto uma edição também precisa de "post-by-id".
O que “use server” faz?
Colocar a diretiva "use server" no início do corpo de uma função faz com que ela seja executada no servidor, mesmo quando é chamada a partir de um componente. É por isso que uma query marcada dessa forma pode ler segredos de process.env e dados de sessão. A documentação de data fetching da v2 demonstra isso com useSession de @solidjs/start/http em seu exemplo exclusivo de servidor.
Coloque dentro de "use server" | Mantenha fora |
|---|---|
Segredos de ambiente (process.env.*) | APIs do navegador (window, localStorage, DOM) |
| Acesso a banco de dados e sessão | Estado de UI que vive nos componentes |
Helpers de @solidjs/start/http | Qualquer coisa que precise rodar em um clique sem fazer uma requisição |
Em uma aplicação SolidStart, o estado de UI pertence ao cliente. O servidor guarda os dados, e signals e stores guardam o estado de interação, uma divisão abordada em gerenciamento de estado no SolidJS.
O SolidStart v2 também reconhece os imports marcadores server-only e client-only. Adicione um deles a um módulo, e importá-lo do lado errado (código de servidor no cliente, ou o contrário) quebra o servidor de desenvolvimento ou o build, de modo que o erro nunca chega aos usuários. A referência de configuração lista @solidjs/start/http e @solidjs/start/middleware como já marcados como server-only. Durante o desenvolvimento, você também conta com uma barra de ferramentas que exibe erros da aplicação e chamadas de server functions. Ela nunca é incluída em um build de produção.
Modos de renderização no SolidStart
No SolidStart v2, o comportamento de renderização é configurado pelo plugin solidStart() e pelo plugin de deploy com o qual você o combina, ambos declarados em vite.config.ts. Para os trade-offs conceituais entre renderização no servidor, streaming e geração estática, veja os 10 principais padrões de renderização. Esta seção aborda apenas onde essas escolhas ficam no SolidStart.
Como app.config.ts não existe mais, qualquer flag de renderização da era v1 que você encontrar em posts antigos não se aplica da forma como está escrita. Para conhecer as opções que a v2 expõe, consulte a referência de configuração de solidStart() e a documentação dos plugins de deploy.
Quando uma página é renderizada no servidor, os usuários veem o markup antes de o JavaScript do cliente fazer a hidratação. Replays de sessão de aplicações SSR tornam esse intervalo visível: o usuário toca em um botão que aparece corretamente, mas não faz nada, e depois toca de novo quando os handlers são anexados.
Deploy do SolidStart v2
O SolidStart v2 não tem adaptadores de hospedagem próprios. O deploy é feito por meio de plugins do Vite, e o anúncio da v2 cita três alvos suportados: o plugin Vite do Nitro v3 (ainda em beta, segundo esse anúncio), o plugin Vite da Cloudflare e o plugin Vite da Netlify. O guia de primeiros passos aponta para uma página de plugins de deploy que cobre a configuração do runtime de produção de cada um.
O ecossistema é o verdadeiro custo de escolher o SolidStart em vez de uma stack React. O React tem muito mais bibliotecas de componentes de terceiros, integrações de autenticação e templates de hospedagem, e equipes que usam Solid escrevem por conta própria boa parte desse código de integração. A comparação entre SolidJS e React contrapõe essa diferença ao modelo de renderização do Solid. Tenha em mente também que o SolidStart v2 está em modo de manutenção enquanto o Solid 2.0 avança em direção ao modo Start.
Conclusão
O SolidStart v2 é uma forma estável e nativa do Vite de adicionar renderização no servidor a aplicações Solid v1. O carregamento de dados se resume a três peças: query, createAsync e uma diretiva "use server", com route.preload para buscar dados antecipadamente. O próximo passo é criar um projeto com npm init solid, adicionar as duas rotas de posts mostradas acima e, em seguida, implementar uma mutation usando a seção de mutação de dados da documentação da v2.
Perguntas frequentes
O SolidStart v2 funciona com o Solid 2.0?
Não. O SolidStart v2 foi feito para o Solid 1.x, e nenhuma release do SolidStart tem como alvo o Solid 2.0. O Release Candidate do Solid 2.0 aposenta o SolidStart e distribui suas peças em outros lugares: o núcleo do Solid passa a cuidar das server functions, o modo Start faz o serving e um pacote separado, independente de router, cuida do roteamento baseado no sistema de arquivos. Aplicações SolidStart existentes continuam funcionando, o SolidStart ainda recebe releases de manutenção e um guia de migração oficial cobre a transição para o modo Start.
Qual é a diferença entre o TanStack Start e o SolidStart com TanStack Router?
São opções distintas. O SolidStart v2 é agnóstico em relação ao router e funciona tanto com o Solid Router v1 oficial quanto com o TanStack Solid Router v1, então você pode usar o roteamento do TanStack sem sair do SolidStart. O TanStack Start é um metaframework separado com uma variante para Solid, publicada como @tanstack/solid-start, e já tem uma release beta para o Solid 2.0. Para o Solid 2.0, o starter fullstack-tanstack combina o modo Start com o TanStack Router e o TanStack Query.
O que são single-flight mutations no SolidStart?
Single-flight mutations enviam os dados atualizados de volta na mesma resposta do servidor que a própria mutation. Quando uma action executada no servidor altera dados que a view atual carregou via preload, ou redireciona para uma página cujos dados são carregados via preload, o SolidStart revalida esses dados no servidor e os entrega na mesma ida e volta. O cliente não precisa fazer um segundo conjunto de requisições, então não há cascata de requisições após uma gravação.
O que muda ao atualizar uma aplicação SolidStart v1 para a v2?
A atualização exige Node.js 24 e Vite 8. A configuração do framework sai do app.config.ts e vai para o vite.config.ts, onde solidStart() é registrado como plugin do Vite, e a Environment API do Vite substitui o Vinxi. O guia de migração oficial também detalha o que mudou em caminhos de import, tipos de ambiente do TypeScript, runtime do servidor e middleware. Revise os caminhos de import e o código de middleware da v1 com base no guia, em vez de copiá-los sem alterações.
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