Initialisation projet React Router 7 : setup Tailwind, shadcn, Zod
Apprends à lancer ton projet React Router 7 de zéro, avec Tailwind, shadcn/ui et validation Zod. Pose des bases saines pour coder ton e-commerce.
Pourquoi repartir d’un projet nu ?
- 0 code « magique » caché dans un boilerplate.
- Tu comprends chaque dépendance ajoutée.
- Tu règles toi-même les bugs sans fouiller un template XXL.
Les stacks citées dans la vidéo :
- Epic Stack – impressionnante, mais blindée de features inutiles pour notre boutique (SQLite, Playwright, etc.).
- Base Stack (Forge 42) – plus légère, mais encore trop de pré-configuration.
- Better-T-Stack – générateur clé-en-main, pratique… un peu trop abstrait pour notre objectif.
👉 On part donc d’un dossier vide et on ajoute uniquement ce dont on a besoin.
Étape 1 – créer le squelette React Router 7
1npx create-react-router@latest shop-router2cd shop-router3npm install4npm run dev
create-react-routergénère un projet Vite + React Router 7.- Vite lance le serveur sur
localhost:5173, la page par défaut s’affiche.
Étape 2 – pousser sur GitHub (CI à venir)
1git init2git add .3git commit -m "feat: boot React Router 7"4git branch -M main5git remote add origin git@github.com:<ton-user>/shop-router.git6git push -u origin main
Pourquoi tout de suite ?
- Tu pourras brancher GitHub Actions dès le module « Déploiement ».
- Chaque leçon = une PR dédiée, historique clair.
Étape 3 – installer Tailwind CSS + shadcn/ui
- shadcn/ui installe et configure Tailwind v4 pour toi :
Terminal1npx shadcn-ui@latest init # choix du thème « stone »
- On récupère tous les composants par défaut (boutons, inputs, etc.) :
shadcn ajoute :Terminal1npx shadcn-ui@latest add --all
- la police Inter pré-connectée dans
app/root.tsx, app/app.cssrempli des variables CSS,- une cinquantaine de composants Radix stylés.
- la police Inter pré-connectée dans
Étape 4 – première vérification visuelle
1import { Button } from "~/components/ui/button";23export default function Home() {4return (5<main className="grid place-content-center min-h-screen">6<Button className="text-xl">Bienvenue sur Shop Router !</Button>7</main>8);9}
HMR de Vite ↔ Tailwind : la couleur change instantanément.
Étape 5 – ajouter la validation Zod + Conform v3
1npm install zod@3.25 @conform-to/react@ @conform-tozod@3
5.1 – définir un schéma
1import { z } from "zod";23export const LoginSchema = z.object({4email: z.string().email("Email invalide"),5});
5.2 – hook Conform dans la page
1import {2useForm,3getFormProps,4getInputProps,5} from "@conform-to/react";6import { getZodConstraint, parseWithZod } from "@conform-to/zod";7import { Form, useActionData, data, type ActionFunctionArgs } from "react-router";8import { Field } from "~/components/forms"; // composant copié d’EpicStack9import { Button } from "~/components/ui/button";10import { LoginSchema } from "~/utils/login-schema";1112export async function action({ request }: ActionFunctionArgs) {13const fd = await request.formData();14const submission = parseWithZod(fd, { schema: LoginSchema });15if (submission.status !== "success") {16return data({ result: submission.reply() }, { status: 400 });17}18return data({ result: submission.reply() });19}2021export default function Home() {22const actionData = useActionData<typeof action>();2324const [form, fields] = useForm({25lastResult: actionData?.result,26constraint: getZodConstraint(LoginSchema),27onValidate({ formData }) {28return parseWithZod(formData, { schema: LoginSchema });29},30});3132return (33<Form method="POST" {...getFormProps(form)} className="w-80 space-y-5">34<Field35labelProps={{ children: "Email" }}36inputProps={getInputProps(fields.email, { type: "email" })}37errors={fields.email.errors}38/>39<Button className="w-full" type="submit">40Continuer41</Button>42</Form>43);44}
Explications :
useFormgère l’état, la validation client et la synchro avec la réponse serveur.Field(issu de l’EpicStack) affiche label + input + erreurs, accessibilité comprise.action()re-valide côté serveur et renvoie400si besoin.
Résultat : un champ e-mail qui clignote rouge dès qu’il est invalide… sans écrire une seule ligne de useState.
Étape 6 – commit / PR « Initialisation »
1git checkout -b 7-1-initialisation-projet2git add .3git commit -m "feat: Tailwind + shadcn + Zod + Conform + formulaire email"4git push -u origin 7-1-initialisation-projet
Crée la Pull Request, vérifie les fichiers ajoutés (composants shadcn, forms.tsx, etc.) puis merge vers main.
Ce que tu as maintenant
- Un projet React Router 7 nu, propre, versionné.
- Tailwind CSS + shadcn/ui prêts pour styler ton e-commerce.
- Zod + Conform configurés pour tous les formulaires futurs.
- Un premier champ e-mail validé client + serveur.
Prochaine étape 👉 initialiser Prisma + PostgreSQL pour stocker tes produits et utilisateurs.
Comprendre les concepts fondamentaux
Quelle est la principale différence entre les composants client et serveur dans React ?
Optimisation des performances
Quelle technique est recommandée pour éviter les rendus inutiles dans React ?
Architecture des données
Quel hook permet de gérer les effets de bord dans un composant React ?