vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.06k stars 26.71k forks source link

Router.push takes to incorrect page but refreshing same exact URL opens correct page. #45000

Open gauravsaini964 opened 1 year ago

gauravsaini964 commented 1 year ago

Verify canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 22.2.0: Fri Nov 11 02:04:44 PST 2022; root:xnu-8792.61.2~4/RELEASE_ARM64_T8103
Binaries:
  Node: 16.18.1
  npm: 8.19.2
  Yarn: 1.22.19
  pnpm: N/A
Relevant packages:
  next: 13.1.1
  eslint-config-next: 13.1.1
  react: 18.2.0
  react-dom: 18.2.0

Which example does this report relate to?

catch-all-routes

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

Vercel

Describe the Bug

For some reason, my dynamic route is rendered instead of catch all route when I use router.push or Link component. But when I refresh the page, the exact same url renders correct catch all route page. Folder layout attached below.

image

getStaticPath Reference

pages/[category-slug]/[...category-concern-filter-slug]/index.jsx

export async function getStaticPaths(context) {
  let publicationState = context.preview ? "PREVIEW" : "LIVE";

  const { data: consolidatedData } = await gqlClient.query({
    query: getCategoryWiseFilterHabitsConcerns,
    variables: { publicationState: publicationState },
  });

  let combination = {};

  const paths = consolidatedData.categories.data.map((category) => {
    combination[category.attributes.url] = { concerns: [] };
    return category.attributes.concerns.data.map((concern) => {
      combination[category.attributes.url].concerns.push(concern.attributes.url);
      return {
        params: {
          "category-concern-filter-slug": [`shop-by-${category.attributes.url}-concern`, concern.attributes.url],
          "category-slug": category.attributes.url,
          filterType: "concern",
          concern: concern.attributes.url,
          tissueType: null,
        },
      };
    });
  });

  const tissueTypeDataPaths = consolidatedData.categories.data.map((category) => {
    combination[category.attributes.url] = { ...combination[category.attributes.url], tissueType: [] };
    return category.attributes.tissueTypes.data.map((tissueType) => {
      combination[category.attributes.url].tissueType.push(tissueType.attributes.url);
      return {
        params: {
          "category-concern-filter-slug": [`shop-by-${category.attributes.url}-type`, tissueType.attributes.url],
          "category-slug": category.attributes.url,
          filterType: "tissueType",
          concern: null,
          tissueType: tissueType.attributes.url,
        },
      };
    });
  });

  let combiPaths = [];

  for (const [key, value] of Object.entries(combination)) {
    let combinations = value.concerns.flatMap((d) => value.tissueType.map((v) => v + "-&-" + d));
    combinations.map((combo) => {
      combiPaths.push({
        params: {
          "category-concern-filter-slug": [`shop-by-${key}-type-&-concern`, combo],
          "category-slug": key,
          filterType: "combination",
          concern: combo.split("-&-")[1],
          tissueType: combo.split("-&-")[0],
        },
      });
    });
  }

  const finalPath = [...paths, ...tissueTypeDataPaths, ...combiPaths];

  // console.log("finalPath", finalPath);

  return {
    paths: finalPath.flat(),
    fallback: false,
  };
}

pages/[category-slug]/[collection-slug]/[product-slug]/index.jsx

export async function getStaticPaths(context) {
  let publicationState = context.preview ? "PREVIEW" : "LIVE";
  const { data } = await gqlClient.query({
    query: getAllProductName,
    variables: { publicationState: publicationState },
  });

  const paths = data.products.data.map((item) => {
    return {
      params: {
        "category-slug": item.attributes.collections.data[0].attributes.category.data.attributes.url,
        "collection-slug": item.attributes.collections.data[0].attributes.url,
        "product-slug": item.attributes.url,
      },
    };
  });
  // console.log(paths);
  return {
    paths,
    fallback: false,
  };
}

Expected Behavior

When I go to this url /hair/shop-by-hair-type-&-concern/dry-scalp-&-dandruff. Page stating 'concernssss' renders which is correct. That file is located at pages/[category-slug]/[...category-concern-filter-slug]/index.jsx

When I try to do Router.push('/hair/shop-by-hair-type-&-concern/dry-scalp-&-dandruff'), it takes me to the error page which is trying to render file located at pages/[category-slug]/[collection-slug]/[product-slug]/index.jsx

Screenshot 2023-01-18 at 4 58 34 PM Screenshot 2023-01-18 at 4 58 15 PM

To Reproduce

Have catch all route in same directory as dynamic route and try Router.push.

samuelcole commented 3 weeks ago

I believe this is happening to us as well: we have a /objects/new page, and after we submit the form we want to router.push to /objects, but that does not trigger a page change.

I suspect it's because we have a /objects/[objectId]/index.tsx route, so I think next.js thinks we are changing the objectId param rather than visiting a different route.

We fixed it by manually triggering router.push('/objects/index', '/objects')