Next.js
React
TypeScript
Tailwind CSS
Vercel
Portfolio
Développement Web

Comment j'ai créé mon portfolio avec Next.js et Vercel

Mouhssine Lakhili profile
Mouhssine Lakhili
12 janvier 20257 min de lecture

Un tour d'horizon de la création d'un portfolio de développeur moderne, performant et optimisé pour le SEO avec Next.js 13, TypeScript, Tailwind CSS et Vercel. Je détaille mes choix d'architecture, les optimisations et les bonnes pratiques.

Comment j'ai créé mon portfolio avec Next.js et Vercel
Image de couverture: Comment Mouhssine Lakhili a construit un portfolio Next.js avec Vercel et une base SEO propre.

Introduction

En tant que développeur full-stack, un portfolio professionnel est essentiel pour mettre en avant vos compétences auprès des recruteurs et des clients potentiels. Après avoir évalué plusieurs frameworks et approches, j'ai choisi de construire mon portfolio avec Next.js 13, TypeScript et Tailwind CSS, puis de le déployer sur Vercel.

Dans cet article, je vous présente les décisions clés, l'architecture et les optimisations qui rendent ce portfolio efficace. Que vous souhaitiez créer votre propre portfolio ou simplement mieux comprendre les pratiques modernes du web, ce guide vous apportera des informations utiles.

Pourquoi Next.js ?

Next.js est devenu mon framework de référence pour les applications React, et voici pourquoi il convient parfaitement à un portfolio :

Rendu côté serveur et génération statique

Next.js propose plusieurs stratégies de rendu nativement :

// Static Site Generation (SSG) - Idéal pour un portfolio
export async function generateStaticParams() {
  const posts = getAllPostSlugs();
  return posts.map((slug) => ({ slug }));
}

// Cette page est générée au build
export default function BlogPost({ params }: { params: { slug: string } }) {
  const post = getPostBySlug(params.slug);
  return <Article post={post} />;
}

Pour un portfolio, la génération statique (SSG) est idéale car :

  • Le contenu change peu
  • Les pages se chargent instantanément (HTML pré-généré)
  • Excellent SEO (les moteurs peuvent crawler facilement)
  • Pas de coût serveur (fichiers statiques)

Architecture App Router

Next.js 13 introduit l'App Router, que j'ai utilisé pour une organisation claire :

app/
+-- layout.tsx        # Layout racine avec providers
+-- page.tsx          # Page d'accueil
+-- blog/
¦   +-- page.tsx      # Listing du blog
¦   +-- [slug]/
¦       +-- page.tsx  # Article individuel
+-- globals.css

Ce routage par fichiers rend la base de code intuitive et facile à maintenir.

TypeScript pour la sûreté de typage

TypeScript ne sert pas qu'à éviter des erreurs : il documente le code et améliore l'outillage :

// Définitions de types pour les articles
export type BlogPostFrontmatter = {
  title: string;
  description: string;
  author: string;
  date: string;
  tags: string[];
  coverImage: string;
  published: boolean;
  seoTitle?: string;
  seoDescription?: string;
};

export type BlogPost = {
  slug: string;
  frontmatter: BlogPostFrontmatter;
  content: string;
  readingTime: {
    text: string;
    minutes: number;
    words: number;
  };
};

Avec ces types, l'IDE propose l'autocomplétion, détecte les fautes et facilite le refactoring.

Styliser avec Tailwind CSS

J'ai choisi Tailwind CSS pour son approche utility-first et son excellente expérience développeur :

// Composant lisible avec Tailwind
function ProjectCard({ project }: { project: Project }) {
  return (
    <div className="group relative overflow-hidden rounded-xl border border-border bg-card transition-all hover:shadow-lg">
      <div className="aspect-video relative">
        <Image
          src={project.image}
          alt={project.title}
          fill
          className="object-cover transition-transform group-hover:scale-105"
        />
      </div>
      <div className="p-6">
        <h3 className="text-xl font-bold text-foreground mb-2">
          {project.title}
        </h3>
        <p className="text-muted-foreground line-clamp-2">
          {project.description}
        </p>
      </div>
    </div>
  );
}

Variables CSS pour le thème

J'utilise des variables CSS pour un système clair/sombre robuste :

:root {
  --background: 0 0% 98%;
  --foreground: 215 25% 15%;
  --primary: 0 84% 60%;
  --muted: 215 20% 95%;
}

.dark {
  --background: 224 27% 6%;
  --foreground: 210 40% 95%;
  --primary: 0 90% 65%;
  --muted: 224 27% 12%;
}

Cette approche permet un changement de thème fluide sans logique complexe.

Optimisations de performance

La performance est essentielle pour l'expérience utilisateur et le SEO. Voici ce que j'ai mis en place :

Optimisation des images

Le composant Image de Next.js gère l'optimisation automatiquement :

import Image from 'next/image';

<Image
  src={post.coverImage}
  alt={post.title}
  fill
  priority // Charger les images au-dessus de la ligne de flottaison
  sizes="(max-width: 768px) 100vw, 60vw"
  className="object-cover"
/>

Découpage du code

Next.js découpe le code par route, et j'utilise aussi des imports dynamiques :

import dynamic from 'next/dynamic';

// Charger uniquement si nécessaire
const ProjectsSection = dynamic(
  () => import('@/components/sections/projects'),
  { loading: () => <ProjectsSkeleton /> }
);

Optimisation des polices

next/font élimine le layout shift et optimise le chargement :

import { Syne } from 'next/font/google';

const syne = Syne({
  subsets: ['latin'],
  weight: ['400', '500', '600', '700', '800'],
  display: 'swap',
});

Mise en oeuvre SEO

Pour un portfolio, le SEO est critique. Voici mon approche :

Métadonnées dynamiques

export async function generateMetadata({ params }): Promise<Metadata> {
  const post = getPostBySlug(params.slug);

  return {
    title: `${post.frontmatter.title} | Mouhssine Lakhili`,
    description: post.frontmatter.description,
    openGraph: {
      title: post.frontmatter.title,
      description: post.frontmatter.description,
      type: 'article',
      publishedTime: post.frontmatter.date,
      authors: [post.frontmatter.author],
    },
    twitter: {
      card: 'summary_large_image',
      title: post.frontmatter.title,
      description: post.frontmatter.description,
    },
  };
}

Données structurées (JSON-LD)

J'ajoute du schema markup pour les résultats enrichis :

const jsonLd = {
  '@context': 'https://schema.org',
  '@type': 'BlogPosting',
  headline: post.frontmatter.title,
  description: post.frontmatter.description,
  author: {
    '@type': 'Person',
    name: 'Mouhssine Lakhili',
  },
  datePublished: post.frontmatter.date,
  image: post.frontmatter.coverImage,
};

<script
  type="application/ld+json"
  dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>

Génération automatique du sitemap

Un script pre-build génère le sitemap :

// scripts/generate-sitemap.js
function generateSitemap() {
  const blogPosts = getBlogPosts();

  const urls = [
    { loc: SITE_URL, priority: '1.0' },
    { loc: `${SITE_URL}/blog`, priority: '0.8' },
    ...blogPosts.map(post => ({
      loc: `${SITE_URL}/blog/${post.slug}`,
      priority: '0.7',
      lastmod: post.date,
    })),
  ];

  // Generate XML...
}

Internationalisation (i18n)

Mon portfolio supporte l'anglais, le français et l'espagnol :

const translations = {
  en: {
    'nav.home': 'Home',
    'nav.about': 'About',
    'nav.projects': 'Projects',
    // ...
  },
  fr: {
    'nav.home': 'Accueil',
    'nav.about': 'A propos',
    'nav.projects': 'Projets',
    // ...
  },
  es: {
    'nav.home': 'Inicio',
    'nav.about': 'Acerca de',
    'nav.projects': 'Proyectos',
    // ...
  },
};

Grâce à un contexte React, le changement de langue est fluide et persistant.

Déploiement sur Vercel

Vercel offre la meilleure expérience pour déployer Next.js :

  1. Zéro configuration : connecter le repo GitHub
  2. Prévisualisations : chaque PR a son URL
  3. Edge network : contenu servi dans 100+ localisations
  4. Analytics : monitoring de performance intégré
# C'est vraiment tout ce qu'il faut
vercel deploy

Points clés

Construire ce portfolio m'a appris plusieurs leçons importantes :

  1. Commencer par la performance : plus simple que d'optimiser a posteriori
  2. Tout typer : TypeScript évite des bugs en production
  3. SEO dès le début : structurez le contenu tôt
  4. Accessibilité : HTML sémantique et ARIA
  5. Garder simple : éviter la sur-ingénierie

Et ensuite ?

Je continue d'améliorer ce portfolio. Prochaines évolutions :

  • Flux RSS pour le blog
  • Suivi du nombre de vues
  • Intégration newsletter
  • Plus de composants interactifs

Conclusion

Construire un portfolio, ce n'est pas seulement montrer des projets : c'est démontrer ses compétences en action. Chaque ligne de code, chaque décision de design et chaque optimisation parlent à vos employeurs et clients.

Si vous envisagez de créer votre propre portfolio, je vous recommande de commencer avec Next.js. L'expérience développeur est excellente, les performances sont remarquables et l'écosystème est riche.

N'hésitez pas à explorer mon GitHub pour d'autres projets, ou a consulter ma page profil, ma page recrutement et ma page freelance si vous avez des questions.


Vous voulez discuter de cet article ou poser des questions sur la creation de votre portfolio ? Retrouvons-nous sur LinkedIn ou Twitter.

Articles lies

Construire avec l IA et livrer proprement

Besoin d un developpeur capable de transformer une idee en livrable ?

J aide les equipes a livrer du React, Next.js, Node.js, de l IA et de l automatisation avec un cadrage clair, des garde-fous utiles et une execution rapide.

Partager cet article

Articles similaires