I don't understand why when I refresh a page in my nextjs app, I always get back to the index page. I have an e-commerce SPA with a catalogue page in index.js and and the products are displayed through the dynamic [name].js page. If I navigate through the browser refresh or back button, the routing is a mess. I think I miss something in the good practices of nextjs.
index.js
import Head from "next/head";
import Catalogue from "../../components/Catalogue";
import { getProducts } from "../../utils/api";
const HomePage = ({ products }) => {
return (
<div>
<Head>
<title>Catalogue</title>
<meta
name="description"
content="Classe moyenne éditions publie des livres et multiples d'artistes, émergeants ou reconnus, en France et à l'international."
/>
<meta
name="keywords"
content="Edition d'artiste, Livres, prints, multiples, art books, librairie, concept store, Bookshop, Bookstore"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</Head>
<Catalogue products={products} />
</div>
);
};
export async function getStaticProps() {
const products = await getProducts();
return { props: { products } };
}
export default HomePage;
[name].js
const ProductPage = ({ product }) => {
const router = useRouter();
if (router.isFallback) {
return <div>Loading products...</div>;
}
return (
<div className="wrapper">
<Head>
<title>
{product.name} {product.author}
</title>
</Head>
<div className="col right" key={product.id}>
<div className="colophon" key={product.id}>
<p>
{product.annee}
<br />
Format : {product.size} <br />
{product.pages} pages
<br />
{product.cover} <br />
Printing : {product.printing}
<br />
Paper : {product.paper}
<br />
{product.copies} exemplaires
<br />
{product.price} € + Shipping
<br />
<br />
</p>
<div className="colophon">
<p style= {{
width: '50%',
textAlign: 'end',
color: '#6223f5' }}>
The website is under maintenance. To order a book, please send us an email at <a href="mailto:hello@cmeditions.fr" style={{ textDecoration: 'underline' }}>Hello</a>
</p>
{product.status === true ? (
<button
className="snipcart-add-item buy-button "
variant="dark"
onMouseEnter={(e) => handleEnter(e)}
onMouseOut={(e) => handleExit(e)}
data-item-id={product.id}
data-item-price={product.price}
data-item-url={router.asPath}
data-item-image={getStrapiMedia(product.grid_pic.url)}
data-item-name={product.name}
data-item-description={product.author}
v-bind="customFields"
>
BUY ME!
</button>
) : (
<div className="text-center mr-10 mb-1">
<div
className="p-2 bg-indigo-800 items-center text-indigo-100 leading-none lg:rounded-full flex lg:inline-flex"
role="alert"
>
<span className="flex rounded-full bg-indigo-500 uppercase px-2 py-1 text-xs font-bold mr-3">
Coming soon...
</span>
<span className="font-semibold mr-2 text-left flex-auto">
This article is not available yet.
</span>
</div>
</div>
)}
</div>
</div>
</div>
</div >
);
};
export default ProductPage;
export async function getStaticProps({ params }) {
const product = await getProduct(params.name);
return { props: { product } };
}
// This function gets called at build time
export async function getStaticPaths() {
// Call an external API endpoint to get products
const products = await getProducts();
// Get the paths we want to pre-render based on posts
const paths = products.map(
(product) => `/books/${product.name}`
);
// We'll pre-render only these paths at build time.
// { fallback: false } means other routes should 404.
return { paths, fallback: false };
}
I read this on the nextjs doc, could it be part of the solution?..
If the page uses an optional catch-all route, supply null, [], undefined or false to render the root-most route. For example, if you supply slug: false for pages/[[...slug]], Next.js will statically generate the page /.