1. Nommage des fichiers ne fais pas deviner
Fais simple : des noms clairs qui disent ce qu'il y a dedans.
- Composants (React/Next.js) â
PascalCase:Navbar.jsx,UserProfile.jsx - Dossiers â
kebab-case:user-profile/,auth-pages/ - Laravel (Blade) â descriptif :
dashboard.blade.php,user-profile.blade.php
RÚgle d'or : si tu dois réfléchir 3 secondes pour deviner le contenu d'un fichier, renomme-le.
2. Organisation simple pas un sac de riz
Structure claire = esprit clair.
React / Next.js
src/
ââ components/ → blocs rĂ©utilisables
ââ pages/ → les vraies pages (Next)
ââ styles/ → CSS / Tailwind
ââ hooks/ → logique rĂ©utilisable
ââ assets/ → images, icĂŽnes
Laravel (frontend)
resources/
ââ views/ → templates Blade
ââ js/ → ton JS (React/Vue/Alpine)
ââ css/ → tes styles
3. Composants : petits mais costauds
Un composant = une mission. Si ton composant gÚre un formulaire + une carte + une notif⊠il est trop gros, découpe-le.
Button.jsxâ un bouton joliLoginForm.jsxâ le formulaire de loginNavbar.jsxâ le menu
4. Styles : pas de carnaval
Choisis une méthode et tiens-toi-y :
- Tailwind â rapide et pratique
- CSS Modules â propre et isolĂ©
- Styled Components â stylĂ© mais peut devenir lourd
Ăvite le mix "Tailwind + inline + CSS global" dans le mĂȘme composant : salade indĂ©chiffrable.
5. Responsive design : pense mobile d'abord
- Teste sur mobile (boutons pas minuscules, espaces qui respirent).
- Utilise des paliers simples (ex. Tailwind
sm,md,lg). - Les images : tailles fluides et max-width Ă 100%.
6. Lisibilité du code
- Formate automatiquement (Prettier) et garde une indentation propre.
- Noms clairs : a, b, x1 â userName, isLoggedIn, cartItems
- Commentaires : utiles seulement quand ça clarifie vraiment.
7. Réutilisation & DRY
- Ne recopie pas le mĂȘme bouton 10 fois â fais un
<Button />réutilisable. - Extrait la logique partagée dans un
hookou une fonction utilitaire.
8. Esthétique & cohérence
- Palette de couleurs cohérente (pas bleu Facebook + vert WhatsApp + orange MTN au hasard).
- Utilise un set d'icĂŽnes homogĂšne (ex. React Icons).
- Laisse respirer avec des marges et espacements réguliers.
9. Git : juste l'essentiel
- Branches :
feature/login-page,fix/navbar-bug - Commits clairs :
feat: add login form fix: mobile navbar refactor: move styles to modules - Un commit = une idée.
10. Mentalité zen
- Code pour ton "toi du futur".
- D'abord ça marche, ensuite c'est beau, enfin c'est rapide.
- Prends des pauses : ton cerveau n'est pas un GPU.
11. Intégration API propre & robuste
Objectif : une couche services/ qui parle Ă l'API, pas de requĂȘtes dispersĂ©es dans les composants.
Next.js (App Router) : privilégie fetch cÎté serveur avec cache/revalidation; cÎté client, gÚre l'état serveur avec React Query.
11.1 Client Axios (cÎté client)
// src/services/api.ts
import axios from "axios";
export const api = axios.create({
baseURL: import.meta.env.VITE_API_URL || process.env.NEXT_PUBLIC_API_URL,
withCredentials: true,
timeout: 15000,
});
api.interceptors.request.use((config) => {
// â ïž PrĂ©fĂšre un cookie httpOnly cĂŽtĂ© serveur; si token en mĂ©moire, ajoute-le ici :
const token = window.__MEMORY_TOKEN__;
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});
api.interceptors.response.use(
(res) => res,
async (error) => {
if (error.response?.status === 401) {
// Option : tenter un refresh (endpoint /auth/refresh) puis rejouer la requĂȘte
// Sinon : rediriger vers /login
}
return Promise.reject(error);
}
);
11.2 React Query (caching & mutations)
// src/app/providers.tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient({
defaultOptions: {
queries: { staleTime: 60_000, retry: 1, refetchOnWindowFocus: false },
},
});
export default function Providers({ children }) {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}
// Exemple d'usage dans un composant client
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { api } from "@/services/api";
function useProjects(page = 1) {
return useQuery({
queryKey: ["projects", page],
queryFn: async () => (await api.get(`/projects?page=${page}`)).data,
});
}
function Projects() {
const qc = useQueryClient();
const { data, isLoading, error } = useProjects(1);
const createProject = useMutation({
mutationFn: (payload) => api.post("/projects", payload),
onSuccess: () => qc.invalidateQueries({ queryKey: ["projects"] }),
});
// ...render
}
11.3 Next.js : revalidation (SSR/ISR)
// Exemple cÎté serveur (App Router)
export default async function Page() {
const res = await fetch(`${process.env.API_URL}/projects`, { next: { revalidate: 60 }});
const data = await res.json();
// ...render
}
12. Auth & sécurité ne fuis pas, c'est simple
- Tokens : privilégie cookies httpOnly (avec
SameSite=Lax/Strict,Secure). Ăvite le stockage persistant de l'access token enlocalStorage. - CSRF : protĂšge les requĂȘtes mutantes (POST/PUT/DELETE).
- CSP : limite les sources (
Content-Security-Policy). - XSS : jamais d'HTML brut non nettoyé; évite
dangerouslySetInnerHTMLsans sanitation.
La sécurité, c'est des petites rÚgles simples appliquées partout, pas un gros patch à la fin.
13. Formulaires & validation clairs pour l'utilisateur
Combo recommandé : react-hook-form + zod pour valider et afficher des messages propres.
// schema.ts
import { z } from "zod";
export const loginSchema = z.object({
email: z.string().email(),
password: z.string().min(8)
});
// LoginForm.tsx
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { loginSchema } from "./schema";
const { register, handleSubmit, formState: { errors, isSubmitting } } =
useForm({ resolver: zodResolver(loginSchema) });
function onSubmit(values) { /* appeler le service d'auth */ }
14. Services tiers brancher sans polluer
- Monitoring : Sentry pour erreurs JS; init léger + DSN public.
- Analytics : GA4 ou PostHog; événements nommés proprement (
feature_action). - Paiement : Stripe; cÎté front = éléments UI + tokens, jamais de clé secrÚte.
- Uploads : Cloudinary ou S3 presigned URLs.
- Maps : Mapbox/Leaflet selon besoin.
- Push : OneSignal (web push) si utile.
// Exemple Sentry (browser)
import * as Sentry from "@sentry/browser";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 0.1,
});
15. Observabilité & UX erreurs pro qualité
- Toasts pour retours rapides; pages d'erreur amicales.
- Error Boundary pour les crashs UI.
- Logs cÎté client (niveau debug en dev seulement).
// Error boundary minimal
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() { return { hasError: true }; }
render() { return this.state.hasError ? <p>Oups, un souci.</p> : this.props.children; }
}
16. Sources d'inspiration design đš pour des maquettes qui claquent
Parce qu'un bon dev sait aussi oĂč trouver de l'inspiration visuelle !