Vincent Barrault

Créer un blog avec NextJs

Créer un blog avec NextJs

Table des matières

Contexte

NextJS est un Framework basé sur React qui permet de faire de la génération de pages statiques: idéal pour faire un blog.

Installation

Pour démarrer un projet NextJS, nous allons avoir besoin de node, yarn et de git

npx create-next-app my-blog --use-npm --example "https://github.com/vercel/next-learn-starter/tree/master/learn-starter"
cd my-blog

Créer quelques articles

Pour commencer, nous allons créer quelques articles pour avoir de la matière à afficher. Nous allons utiliser le markdown comme format de fichier.

Pour cela, créez un dossier content à la racine du projet, et mettez y les 3 fichiers suivants

./content/1er-article.md
---
title: 1er article
date: '2020-01-01'
---

Ici le contenu de notre premmier article
./content/2eme-article.md
---
title: 2ème article
date: '2020-01-02'
---

Ici le contenu de notre deuxième article
./content/3eme-article.md
---
title: 3ème article
date: '2020-01-03'
---

Ici le contenu de notre troisième et dernier article

Faire un repository

Tout d'abord, nous allons ajouter quelques dépendances au projet

yarn add gray-matter remark remark-html
yarn add --dev typescript @types/react @types/node

Une fois que nous avons de la donnée, nous allons créer un repository pour y accéder.

Pour cela, créez un dossier repository à la racine du projet, et créez y un fichier articles.ts

./repository/articles.ts
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import remark from 'remark'
import html from 'remark-html'

export interface Article {
    id: string;
    title: string;
    date: string;
    content?: string;
}

export function getArticleList(): Article[] {
    return list()
        .map(fileName => ({
            id: fileName.replace(/\.md$/, ''),
            ...read(fileName).data
        } as Article))
        .sort((a: any, b: any) => a.date < b.date ? 1 : -1);
}

export function getArticleIds() {
    return list().map(fileName => fileName.replace(/\.md$/, ''));
}

export async function getArticle(id: string): Promise<Article> {
    const matterResult = read(`${id}.md`);
    const processedContent = await remark()
        .use(html)
        .process(matterResult.content)

    return {
        id,
        content: processedContent.toString(),
        ...matterResult.data
    } as Article;
}

export function list(): string[] {
    return fs.readdirSync(path.join(process.cwd(), 'content'));
}

export function read(name: string): matter.GrayMatterFile<string> {
    return matter(fs.readFileSync(path.join(process.cwd(), 'content', name), 'utf8'));
}

Créer les premières pages du blog

Une fois notre repository créé, nous pouvons créer une page pour afficher la liste de tous les articles. Si ce n'est pas déjà fait, rajoutez un fichier index.tsx dans le dossier pages de votre projet et remplissez le comme cela.

./pages/index.tsx
import { GetStaticProps } from 'next'
import Head from 'next/head'
import Link from 'next/link'
import { getArticleList } from '../repository/articles'

export default function ArticleList({ articles }) {
    return (
        <div>
            <Head>
                <title>Mon super Blog</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>

            <h1>Articles</h1>

            {articles.map(({ id, date, title }) => (
                <Link href={`/${id}`} key={id}>
                    <div className="article">
                        <h3>{title}</h3>
                        <div>{date}</div>
                    </div>
                </Link>
            ))}

            <style jsx>{`
                .article {
                    background: #eaeaea;
                    padding: 10px 20px;
                    margin: 20px 0;
                }
            `}</style>
        </div>
    )
}

export const getStaticProps: GetStaticProps = async () => {
    return {
        props: {
            articles: getArticleList()
        }
    }
}

Enfin, nous pouvons créer une page pour visionner un article en particulier. Pour cela, ajoutez un fichier nommé [id].tsx dans le dossier pages et remplissez le avec le contenu suivant.

./pages/[id].tsx
import { GetStaticPaths, GetStaticProps } from 'next'
import Head from 'next/head'
import { getArticleIds, getArticle } from '../repository/articles'


export default function ArticleShow({ article }) {
    return (
        <div>
            <Head>
                <title>{article.title}</title>
            </Head>

            <div className="article">
                <h1 className="title">{article.title}</h1>
                <div className="date">{article.date}</div>
                <div className="content" dangerouslySetInnerHTML={{ __html: article.content }} />

                <style jsx>{`
                    .title {
                        font-size: 40px;
                    }
                    .date {
                        color: #6e6e6e;
                    }
                    .content {
                        margin-top: 20px
                    }
                `}</style>
            </div>
        </div>
    )
}

export const getStaticProps: GetStaticProps = async (context) => {
    const article = await getArticle(context.params.id.toString())
    return {
        props: {
            article
        }
    }
}

export const getStaticPaths: GetStaticPaths = async () => {
    return {
        paths: getArticleIds().map(id => ({
            params: { id }
        })),
        fallback: false
    }
}

Tester son blog sur son ordinateur

Et voila, l'installation minimale de notre blog est finie, nous pouvons maintenant lancer notre site sur un serveur local grace à la commande

yarn dev

Pour accéder au site, entrez dans la barre de recherche de votre navigateur l'url suivante: http://localhost:3000/

Nous pouvons voir que la liste des 3 articles est récupérée

List d'article

et que si nous cliquons sur un article, le site nous emmène bien vers la page de cet article.

Pade d'article

Dans l'article suivant, nous allons voir comment utiliser GIT et l'intégration continue pour déployer automatiquement le site lorsque nous ajoutons de nouveaux articles.