Next.js: Ensure Next.js parses client-side query post-hydration

Created on 14 Oct 2019  路  4Comments  路  Source: vercel/next.js

In the meantime, using the above ideas here is what I came up with:

import { withRouter } from 'next/router';

export const withPageRouter = Component => {
  return withRouter(({ router, ...props }) => {
    router.query = [
      ...new URLSearchParams((router.asPath || '').split(/\?/)[1]).entries()
    ].reduce((q, [k, v]) => Object.assign(q, { [k]: v }), {});

    return <Component {...props} router={router} />;
  });
};

_Originally posted by @cansin in https://github.com/zeit/next.js/issues/4804#issuecomment-541420735_


We should make sure (add a test) that client-side query strings are correctly merged into statically exported pages post-hydration (for a normal and dynamically routed page).

good first issue story needs investigation

Most helpful comment

@Timer FYI, here is the latest version of the above code that fixes an issue re: getInitialProps and follows the pattern applied at https://github.com/zeit/next.js/blob/canary/packages/next/client/with-router.tsx :

import { withRouter } from 'next/router';
import React from 'react';

export const withPageRouter = ComposedComponent => {
  const WithPageRouteWrapper = withRouter(({ router, ...props }) => {
    router.query = [
      ...new URLSearchParams((router.asPath || '').split(/\?/)[1]).entries()
    ].reduce((q, [k, v]) => Object.assign(q, { [k]: v }), {});

    return <ComposedComponent {...props} router={router} />;
  });

  WithPageRouteWrapper.getInitialProps = ComposedComponent.getInitialProps;
  // I am not 100% about this origGetInitialProps setter.
  WithPageRouteWrapper.origGetInitialProps =
    WithPageRouteWrapper.origGetInitialProps;
  if (process.env.NODE_ENV !== 'production') {
    const name =
      ComposedComponent.displayName || ComposedComponent.name || 'Unknown';
    WithPageRouteWrapper.displayName = `withPageRouter(${name})`;
  }

  return WithPageRouteWrapper;
};

Kudos to @Rameshv for pointing it out.

All 4 comments

@Timer FYI, here is the latest version of the above code that fixes an issue re: getInitialProps and follows the pattern applied at https://github.com/zeit/next.js/blob/canary/packages/next/client/with-router.tsx :

import { withRouter } from 'next/router';
import React from 'react';

export const withPageRouter = ComposedComponent => {
  const WithPageRouteWrapper = withRouter(({ router, ...props }) => {
    router.query = [
      ...new URLSearchParams((router.asPath || '').split(/\?/)[1]).entries()
    ].reduce((q, [k, v]) => Object.assign(q, { [k]: v }), {});

    return <ComposedComponent {...props} router={router} />;
  });

  WithPageRouteWrapper.getInitialProps = ComposedComponent.getInitialProps;
  // I am not 100% about this origGetInitialProps setter.
  WithPageRouteWrapper.origGetInitialProps =
    WithPageRouteWrapper.origGetInitialProps;
  if (process.env.NODE_ENV !== 'production') {
    const name =
      ComposedComponent.displayName || ComposedComponent.name || 'Unknown';
    WithPageRouteWrapper.displayName = `withPageRouter(${name})`;
  }

  return WithPageRouteWrapper;
};

Kudos to @Rameshv for pointing it out.

Regarding #9524

@stephenjang not sure why you're linking to the SSG RFC 馃

Oh I'm sorry. I was tested on dynamic-import with withRouter and getStaticProps examples for SSG. That's misreporting link comment.

Was this page helpful?
0 / 5 - 0 ratings