In my gatsby-node.js
I create dynamic Category pages:
exports.createPages = async ({ graphql, actions: { createPage } }) => {
const {
data: { projects, categories },
} = await graphql(`
query Projects {
projects: allGraphCmsProject(filter: { stage: { eq: PUBLISHED } }) {
nodes {
id
slug
}
}
categories: allGraphCmsCategory {
nodes {
id
slug
}
}
}
`);
projects.nodes.forEach(({ id, slug }) => {
createPage({
path: `${slug}`,
component: path.resolve('./src/templates/ProjectPage.tsx'),
context: { id, slug },
});
});
categories.nodes.forEach(({ id, slug }) => {
createPage({
path: `/category/${slug}`,
component: path.resolve('./src/templates/CategoryPage.tsx'),
context: { id },
});
});
};
Inside src/templates/CategoryPage.tsx
I render a CategoryList.tsx
component.
In the browser on the page /category
(src/pages/category.tsx), I render also the list categories (CategoryList.tsx
component). When I click a category from this page it's working fine and it shows a url like /category/category-one
and shows the categorie page in the browser.
But then if I click another category (from within a category page (src/templates/CategoryPage.tsx
), I get an url like /category/category-one/category-two
?
But then if I click another category (from within a category page (
src/templates/CategoryPage.tsx
), I get an url like/category/category-one/category-two
?
Your page generation looks good, except some unnecessary template literals:
projects.nodes.forEach(({ id, slug }) => {
createPage({
path: slug, // before was path: `${slug}`,
component: path.resolve('./src/templates/ProjectPage.tsx'),
context: { id, slug },
});
});
Your issue appears because you are missing an initial slash (/
) at the beginning of the to
props
of the <Link>
component.
On your category page:
<Link to={`/${slug}`}/>{categoryName}</Link>
Note: I don't know your page structure but the goal is to add an initial slash.
This is because slug
, may come or not with an initial slash. If it doesn't, it will concatenate the current URL to the slug
itself, like an anchor (<a>
) normally does.