Next.js: Next.js useRouter() query: { amp: undefined }

Created on 22 Jul 2019  路  8Comments  路  Source: vercel/next.js

I am having issues passing in query objects to useRouter() hook. I am attempting to capture URL params and pass it into a page component pages/post.js server-side using koa. and koa-router.

I am using Koa.js as my middleware based on next.js example: custom-koa-server
and using Next's documentation: Custom routes (using props from URL)

// server.js

app.prepare().then(() => {
  const server = new Koa();
  const router = new Router();

  router.get("/post/:slug", async ctx => {
    await app.render(ctx.req, ctx.res, "/post", { slug: ctx.params.slug });
    ctx.respond = false;
  });

  router.get("*", async ctx => {
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
  });

  server.use(async (ctx, next) => {
    ctx.res.statusCode = 200;
    await next();
  });

  server.use(router.routes());
  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});
// pages/post.js

import { useRouter } from "next/router";

const Post = () => {
  const router = useRouter();
  console.log(useRouter());
  const { slug } = router.query;

  return <p>My Blog Post: {slug}</p>;
};

export default Post;

useRoute() console.log

// output: console.log(useRoute());

ServerRouter {
  route: '/post',
  pathname: '/post',
  query: { amp: undefined },
  asPath: '/post/testing' }

When attempting to access the query object, no matter what, I get { amp: undefined }

Any help on this will be super helpful! Thank you in advance!

Most helpful comment

It seems a bit user-unfriendly that the router.query is not properly initialized until first render. What's the technical reasoning behind this?

All 8 comments

Hi! Questions belong on our Spectrum, please open a support request there with a reproduction repository.

Also, in your provided code I don't see the need for a custom server, dynamic routes would fulfill your needs:
https://nextjs.org/docs#dynamic-routes

@Timer Thanks! Apologies for the misplacement...issue posted here

oh and the reason why I am not using Dynamic Routes is that this will eventually be a server-side fetch to an API and passed rendered into a page component. Details in the General Channel of Next.js Spectrum.

Does getInitialProps not support what you're trying to do?

i have the same problem锛孒ow did you solve it

@jingyuanhe

All you need to do to resolve this is useEffect to make sure it runs after router has initialized.

For example:

  const [queryId, setQueryId] = useState(null)
  useEffect(()=> {
    if(router && router.query) {
      setQueryId(router.query.id)
    }
  }, [router])

It seems a bit user-unfriendly that the router.query is not properly initialized until first render. What's the technical reasoning behind this?

This is the workaround I used:

const queryString = require('query-string'); // https://www.npmjs.com/package/query-string
const { filters } = queryString.parse(router.asPath.substring(1));

I noticed that router.query was missing the query params as my component was re-rendered, but they were correct on router.asPath. I parse the params manually from that instead.

It seems a bit user-unfriendly that the router.query is not properly initialized until first render. What's the technical reasoning behind this?

There can't be a good reason, it's a bug. The returning of the router object SHOULD block by default, or we should be able to configure it to block until the query attribute has been set.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

swrdfish picture swrdfish  路  3Comments

rauchg picture rauchg  路  3Comments

YarivGilad picture YarivGilad  路  3Comments

lixiaoyan picture lixiaoyan  路  3Comments

jesselee34 picture jesselee34  路  3Comments