Créer une table des matières des fichiers markdown avec Gatsby

Mis à jour le lundi 31 mai 2021 par johackim

Après avoir Initialiser un projet Gatsby et importer vos fichiers markdown, vous pouvez créer automatiquement la table des matière d'un fichier markdown dans Gatsby.

// gatsby-node.js
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
const result = await graphql(`
{
allMarkdownRemark {
edges {
node {
id
html
headings {
value
depth
}
parent {
... on File {
name
}
}
}
}
}
}
`);
if (result.errors) {
reporter.panicOnBuild('Error while running GraphQL query.');
return;
}
const markdowns = result.data.allMarkdownRemark.edges;
const noteTemplate = require.resolve('./src/templates/noteTemplate.js');
markdowns.forEach(({ node }) => {
const { id, html, headings } = node;
createPage({
path: `/${node.parent.name}`,
component: noteTemplate,
context: { id, html, headings },
});
});
};
// src/components/toc.js
import React from 'react';
import { Link } from 'gatsby';
import slugify from 'slugify';
export default ({ headings = [], depthMin = 1, className = '' }) => {
if (!headings.length) return false;
return (
<ul className={className}>
{headings.filter(({ depth }) => depth >= depthMin).map(({ value }) => {
const id = slugify(value, { lower: true, strict: true });
return (
<li key={value}>
<Link to={`#${id}`} title={value}>
{value}
</Link>
</li>
);
})}
</ul>
);
};
// src/templates/noteTemplate.js
import React from 'react';
import Toc from '../components/toc';
export default function Template({ pageContext }) {
const { html, headings } = pageContext;
return (
<>
<Toc headings={headings} depthMin={2} />
<div dangerouslySetInnerHTML={{ __html: html }} />
</>
);
}

Pour créer automatiquement les id sur chaque header, il existe le plugin gatsby-remark-autolink-headers :

yarn add -D gatsby-remark-autolink-headers
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
path: './content',
},
},
{
resolve: 'gatsby-transformer-remark',
options: {
plugins: [
{
resolve: 'gatsby-remark-autolink-headers',
options: {
icon: false,
},
},
],
},
},
],
};