Nextjs page refresh always bring me to index.js

Viewed 2546

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 /.

1 Answers

The format of paths on getStaticPaths is wrong.

Here is the documentation. https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation

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) => ({ params: { name: product.name } })
  );
  // We'll pre-render only these paths at build time.
  // { fallback: false } means other routes should 404.
  return { paths, fallback: false };
}


UPDATE


I've tried your code on local and CSB, and it seemed to work as expected.

You say it only happens in production environment, where are you deploying it? There might be a problem in the deployment process, so you might want to contact your service provider.

Also, I'm wondering where you put the pages directory. nextjs requires the pages directory to be in the root or src directory.

https://nextjs.org/docs/advanced-features/src-directory

Related