Skip to content

Hot Reloading not working in Next.js 9 using custom routing, styled components and withApollo example #16449

Open
@aaronkchsu

Description

Bug report

We are running "dev": "cross-env NODE_ENV=development babel-node src/server.js", to start nextjs in dev mode from our server.js file

We see the compiled successfully message when making changes to the pages/components folder
image

but we do not see any changes or renders on the page until we refresh the page

import express from "express";
import "isomorphic-fetch";
import next from "next";
import projectConfig from "./config";

import { initializeApollo } from "./lib/nextApollo";
import gql from "graphql-tag";

const compression = require("compression");
const apiHost = projectConfig.apiHost;
const currentHost = projectConfig.host;
const env = projectConfig.env;

// export interface Global extends NodeJS.Global {
//   document: Document;
//   window: Window;
//   DEVELOPMENT: any;
//   FOLDER: any;
// }

// declare var global: Global;

global.DEVELOPMENT = projectConfig.env == "DEV" ? true : false;
const dev = global.DEVELOPMENT ? true : false;
const folder = global.DEVELOPMENT ? "src" : "dist";

console.log("IS DEVELOPMENT", dev, "FOLDER", folder);

const app = next({ dev, dir: folder });

const handle = app.getRequestHandler();
const server = express();

server.use(compression());

Describe the bug

Next.js, not rerendering page when changes are made to the app.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Run app
  2. Go to page in a browser
  3. Make a change on page
  4. See compiled successfully but no rerender

Expected behavior

Hot reloading should rerender the page

System information

  • OS: Mac and windows
  • Browser all Browsers
  • Version of Next.js: 9.3 and 9.5
  • Version of Node.js: 12

Code Example

export const resolvers = {
    Mutation: {
        setGlobalVolume: (_, { volume }, { cache }) => {
            // cache.writeData({ data: { globalVolume: volume } });
            return null;
        },
        setGlobalSrc: (_, { id }, { cache }) => {
            // cache.writeData({ data: { globalSrcId: id } });
            return null;
        },
    },
};

const authLink = setContext((_, { headers }) => {
    if (projectConfig.env === "DEV") {
        // get the authentication token from local storage if it exists
        const token = isBrowser
            ? window.localStorage
                ? window.localStorage.getItem("jwt")
                : ""
            : "";

        // return the headers to the context so httpLink can read them
        return {
            headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : "",
            },
        };
    } else {
        return {
            headers: {
                ...headers,
            },
        };
    }
});

// https://www.apollographql.com/docs/react/caching/cache-configuration/
const apolloCache = new InMemoryCache({
    dataIdFromObject(responseObject) {
        switch (responseObject.__typename) {
            case "Bite":
                return `Bite:${responseObject._id}`;
            case "Playlist":
                return `Playlist:${responseObject._id}`;
            case "Category":
                return `Category:${responseObject._id}`;
            case "User":
                return `User:${responseObject._id}`;
            default:
                return defaultDataIdFromObject(responseObject);
        }
    },
    typePolicies: {
        Bite: {
            fields: {
                audio: {
                    original: {
                        merge(existing, incoming, { mergeObjects }) {
                            return existing._id;
                        },
                    },
                },
            },
        },
        Query: {
            queryType: true,
            fields: {
                web: {
                    merge: true,
                    queryType: true,
                },
                twitch: {
                    merge: true,
                    queryType: true,
                },
            },
        },
    },
});

export function initializeApollo(initialState = {}) {
    const _apolloClient = apolloClient || createApolloClient();

    // If your page has Next.js data fetching methods that use Apollo Client, the initial state
    // gets hydrated here
    if (initialState) {
        // Get existing cache, loaded during client side data fetching
        const existingCache = _apolloClient.extract();
        // Restore the cache using the data passed from getStaticProps/getServerSideProps
        // combined with the existing cached data
        _apolloClient.cache.restore({ ...existingCache, ...initialState });
    }
    // For SSG and SSR always create a new Apollo Client
    if (typeof window === "undefined") return _apolloClient;
    // Create the Apollo Client once in the client
    if (!apolloClient) apolloClient = _apolloClient;

    return _apolloClient;
}

export function useApollo(initialState) {
    const store = useMemo(() => initializeApollo(initialState), [initialState]);
    return store;
}

_app.js

import React from "react";
import { ApolloProvider } from "@apollo/client";
import { useApollo } from "../lib/nextApollo";
import * as ReactGA from "react-ga";

import { Helmet } from "react-helmet";

import { Themes } from "@blerp/design";
import { colors } from "../components/theme/Theme";
import { ThemeProvider } from "styled-components";

// https://github.com/vercel/next.js/tree/canary/examples/with-apollo For apollo + nextjs example
export default function App({ Component, pageProps }) {
    const apolloClient = useApollo(pageProps.initialApolloState);

    return (
        <ApolloProvider client={apolloClient}>
            <ThemeProvider
                theme={{
                    ...Themes.mainTheme,
                    colors: colors,
                    mode: "light",
                }}
            >
                <>
                    <Helmet defaultTitle='Blerp' titleTemplate='%s' />
                    <Component {...pageProps} />
                </>
            </ThemeProvider>
        </ApolloProvider>
    );
}

_documents.js

    static async getInitialProps(ctx) {
        const sheet = new ServerStyleSheet();
        const originalRenderPage = ctx.renderPage;
        try {
            ctx.renderPage = () =>
                originalRenderPage({
                    enhanceApp: App => props =>
                        sheet.collectStyles(<App {...props} />),
                });

            const initialProps = await Document.getInitialProps(ctx);
            return {
                ...initialProps,
                styles: (
                    <>
                        {initialProps.styles}
                        {sheet.getStyleElement()}
                    </>
                ),
            };
        } finally {
            sheet.seal();
        }
    }

Metadata

Assignees

No one assigned

    Labels

    good first issueEasy to fix issues, good for newcomersstaleThe issue has not seen recent activity.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions