Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next 9.1.3 withRouter passes router=null on SSR #9350

Closed
macrozone opened this issue Nov 8, 2019 · 13 comments
Closed

next 9.1.3 withRouter passes router=null on SSR #9350

macrozone opened this issue Nov 8, 2019 · 13 comments
Labels
please add a complete reproduction The issue lacks information for further investigation

Comments

@macrozone
Copy link

macrozone commented Nov 8, 2019

Bug report

Describe the bug

withRouter passes prop router: null to wrapped component whereas in next 9.1.2 it always passed the right object (with query, etc.))

import { withRouter } from "next/router";
const Component = ({router}) => {
  console.log(router); // will be null on first render
 return <div>.....</div>
}
withRouter(Component);

To Reproduce

see component above

Expected behavior

withRouter always injects relevant data)

System information

  • OS: macOs

  • Version of Next.js: 9.1.3

Additional context

This bug was not present in 9.1.2 9.1.1. (we skipped 9.1.2)

@macrozone
Copy link
Author

#9105 (comment) suggested that this bug was already present in 9.1.2

have to stick to 9.1.1 now

@timneutkens timneutkens added the please add a complete reproduction The issue lacks information for further investigation label Nov 9, 2019
@timneutkens
Copy link
Member

timneutkens commented Nov 9, 2019

Always provide a full reproduction when creating GitHub issues. This is not enough to reproduce.

Are you using Apollo or urql by any chance?

@macrozone
Copy link
Author

@timneutkens yes, i am using apollo. I just started a reproduction and it does not occure on a fresh nextjs (which was to be expected). So i also thought it has to do with apollo. The apollo client is initialized in _app.jsx according to the older examples (the newer examples don't extend _app anymore, but require you to use a HOC on every page)

@timneutkens
Copy link
Member

You'll have to use AppTree similarly to the newer examples. That's probably where it broke (the older example was doing non-standard behavior).

@macrozone
Copy link
Author

@timneutkens thx, this seems to work.

For other falling into the same issue:

in withApolloClient-HOC, in getMarkupFromTree, it should use <AppTree /> not <App />

it looks something like:

import { getMarkupFromTree } from "@apollo/react-ssr";
import { ApolloClient } from "apollo-boost";
import Head from "next/head";
import nookies from "nookies";
import React from "react";
import { renderToString } from "react-dom/server";
import { initApollo } from "./initApollo";


export default (App) => {
  return class Apollo extends React.Component {
    public static displayName = "withApollo(App)";

    public static async getInitialProps(appContext) {
      let appProps = {};
      const { AppTree } = appContext;
      if (App.getInitialProps) {
        appProps = await App.getInitialProps(appContext);
      }

      const { Component, router, ctx } = appContext;
      const apollo = createApollo(ctx);
      ctx.apollo = apollo;

      if (!process.browser) {
        try {
          // Run all GraphQL queries
          await getMarkupFromTree({
            renderFunction: renderToString,
            tree: (
              <AppTree {...appProps} Component={Component} router={router} apolloClient={apollo} />
            ),
          });
        
        } catch (error) {
          // Prevent Apollo Client GraphQL errors from crashing SSR.
          // Handle them in components via the data.error prop:
          // https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error

          // tslint:disable-next-line:no-console
          console.error("Error while running `getMarkupFromTree`", error);
        }

        // getDataFromTree / getMarkupFromTree does not call componentWillUnmount
        // head side effect therefore need to be cleared manually
        Head.rewind();
      }

      // Extract query data from the Apollo store
      const apolloState = apollo.cache.extract();
      return {
        ...appProps,
        apolloState,
      };
    }

    private apolloClient: ApolloClient<any>;

    constructor(props) {
      super(props);
      this.apolloClient = initApollo(props.apolloState);
    }

    public render() {
      return <App {...this.props} apolloClient={this.apolloClient} />;
    }
  };
};

@macrozone
Copy link
Author

macrozone commented Nov 10, 2019

@timneutkens sadly, i did not realize, that now SSR with apollo is broken. on SSR all components using apollo now render in loading state and apollo.cache.extract(); returns an empty object.

also #9336 seems to have a similar problem.

I now will revert to 9.1.1 and stick to that for the moment, because i think others have similar problems and there was an accidental breaking change between 9.1.1 and 9.1.3

@simeon-smith
Copy link

A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.

To correct this make sure you import withRouter from "next/router";

@macrozone
Copy link
Author

A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.

To correct this make sure you import withRouter from "next/router";

i only include import { WithRouterProps } from "next/dist/client/with-router"; , withRouter is always imported with import { withRouter } from "next/router";

@Serguzest
Copy link

A note in case anyone makes the same mistake I did:
Auto imports could pull withRouter from "next/dist/client/with-router" which will cause this issue.

To correct this make sure you import withRouter from "next/router";

Exactly what happened to me too!

@giovannibenussi
Copy link

For anyone having this issue, in my case, I got this issue using useRouter's hook in a component nested inside a header section (next/head).

Moving the component outside of the head section solved the issue.

I'm using next 9.3.4.

@hackermondev
Copy link

For anyone having this issue, in my case, I got this issue using useRouter's hook in a component nested inside a header section (next/head).

Moving the component outside of the head section solved the issue.

I'm using next 9.3.4.

yes that was my problem too

@nbouvrette
Copy link
Contributor

For anyone having this issue, in my case, I got this issue using useRouter's hook in a component nested inside a header section (next/head).

Moving the component outside of the head section solved the issue.

This is related to #17721

And this is documented https://nextjs.org/docs/api-reference/next/head

ℹ️ As the docs say, you MUST have it as direct children of Head, or wrapped at maximum in one level of <React.Fragment> or arrays.

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
please add a complete reproduction The issue lacks information for further investigation
Projects
None yet
Development

No branches or pull requests

8 participants