vercel / next.js

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

Dynamic routes for AMP pages not resolving #55418

Open rakeshtembhurne opened 1 year ago

rakeshtembhurne commented 1 year ago

Link to the code that reproduces this issue or a replay of the bug

https://github.com/rakeshtembhurne/next-router-amp-dynamic-routes

To Reproduce

  1. Start the application in development
  2. Create a route stories/[...slug].tsx
  3. Enable AMP by adding export const config = { amp: true}
  4. Import and use the router with import { useRouter } from "next/router" and const router = useRouter();
  5. Visit any dynamic URL like http://localhost:3000/stories/some-random-story
  6. Use console.log(router) or try to render router as JSON <pre>{JSON.stringify(router, null, 2)}</pre>, in both cases value of slug is missing in query
  7. Quick full sample code:
import { useRouter } from "next/router"

export const config = { amp: true}

export default function Home() {
    const router = useRouter();

    const { asPath, pathname, route, query } = router;
    console.log({ asPath, pathname, route, query });

    return (<>
        <h1>Output</h1>
        <pre>{JSON.stringify({ asPath, pathname, route, query }, null, 2)}</pre>
    </>)
}

Current vs. Expected behavior

Expected Output

When visiting url: http://localhost:3000/stories/inside/some-random-story, we should get value router.query.slug === "some-random-story" whether amp is enabled or not.

Current Behavior

Case "Without exporting config variable (normally)"

console.log({ asPath, pathname, route, query });

{
  asPath: '/stories/inside/[...slug]',
  pathname: '/stories/inside/[...slug]',
  route: '/stories/inside/[...slug]',
  query: {}
}

<pre>{JSON.stringify({ asPath, pathname, route, query }, null, 2)}</pre>

{
  "asPath": "/stories/inside/some-random-story",
  "pathname": "/stories/inside/[...slug]",
  "route": "/stories/inside/[...slug]",
  "query": {
    "slug": [
      "some-random-story"
    ]
  }
}

Case "with export const config = { amp: true}"

console.log({ asPath, pathname, route, query });

{
  asPath: '/stories/inside/[...slug]',
  pathname: '/stories/inside/[...slug]',
  route: '/stories/inside/[...slug]',
  query: {}
}

<pre>{JSON.stringify({ asPath, pathname, route, query }, null, 2)}</pre>

{
  "asPath": "/stories/inside/[...slug]",
  "pathname": "/stories/inside/[...slug]",
  "route": "/stories/inside/[...slug]",
  "query": {}
}

Case "with export const config = { amp:'hybrid'} AND ?amp=1 at the end of URL"

console.log({ asPath, pathname, route, query });

{
  asPath: '/stories/inside/[...slug]',
  pathname: '/stories/inside/[...slug]',
  route: '/stories/inside/[...slug]',
  query: { amp: '1' }
}

<pre>{JSON.stringify({ asPath, pathname, route, query }, null, 2)}</pre>

{
  "asPath": "/stories/inside/[...slug]",
  "pathname": "/stories/inside/[...slug]",
  "route": "/stories/inside/[...slug]",
  "query": {
    "amp": "1"
  }
}

Verify canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.17.1
      npm: 9.6.7
      Yarn: 1.22.19
      pnpm: 8.5.1
    Relevant Packages:
      next: 13.4.20-canary.30
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.3
    Next.js Config:
      output: N/A

Which area(s) are affected? (Select all that apply)

App Router, Routing (next/router, next/navigation, next/link)

Additional context

No response

rakeshtembhurne commented 1 year ago

Update

I had to add extra code when in AMP mode, to make it work like normal:

export async function getServerSideProps() {
  return { props: {} }
}

Solves my issue, but unsure if it is the right solution for the problem. Either it should be documented or a fix still needs to be worked out.

devmoatassem commented 2 months ago

@rakeshtembhurne can you suggest me how to do it in app router?