Next.js Uncaught SyntaxError: Invalid or unexpected token, then ChunkLoadError: Loading chunk app/layout failed
Asked Answered
H

3

8

I have a pretty minimal app at the moment implementing redux (following the official redux docs) and implementing some persistence of the data to local storage. I am facing a very stressful problem where i get

Uncaught SyntaxError: Invalid or unexpected token (at layout.js:93:29)

in my console. If i leave the error there, the app completely crashed and i get:

Unhandled Runtime Error

ChunkLoadError: Loading chunk app/layout failed. (timeout: http://localhost:3000/_next/static/chunks/app/layout.js))

The thing is that the errors are kind of random. It usually occurs (but not always) in a first page load after running npx next dev

If i reload the page, everything starts working normally until i restart the server. Then the error appears again. I having a hard time trying to debug, specially because it can happen that i run npx next dev 4 ou 5 times and get no error, then it starts appearing again for a random number of server restarts. In any case, always, i can get rid of the error reloading the page.

Current code:

layout.tsx

import type { Metadata } from "next";
import "./globals.css";
import StoreProvider from "./StoreProvider";

export const metadata: Metadata = {
  title: "App",
  description: "App Description",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html>
      <body>
        <StoreProvider>{children}</StoreProvider>
      </body>
    </html>
  );
}

StoreProvider.tsx

"use client";

import { useRef, useEffect } from "react";
import { Provider } from "react-redux";
import { makeStore, AppStore } from "../redux/store";
import { updateUser } from "@/redux/user/userSlice";

export default function StoreProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const storeRef = useRef<AppStore>();

  if (!storeRef.current) {
    // Create the store instance the first time this renders
    storeRef.current = makeStore();
  }

  useEffect(() => {
    if (storeRef.current !== undefined) {
      storeRef.current.dispatch(
        updateUser(JSON.parse(localStorage.getItem("user")!))
      );
    }
  }, []);

  return <Provider store={storeRef.current}>{children}</Provider>;
}

userSlice.ts

import { createSlice } from "@reduxjs/toolkit"

interface userInterface {
    value: {
        id: string | number,
        email: string,
        username: string | null,
        avatar?: string | null,
        name?: string,
        lastname: string,
        isAdmin?: string | boolean

    } | null
}

const initialState: userInterface = {
    value: null
}

const userSlice = createSlice({
    name: 'user',
    initialState,
    reducers: {
        updateUser: (state, action) => {
            state.value = action.payload
            localStorage.setItem('user', JSON.stringify(state.value))
        },
        clearUser: (state) => {
            state.value = null
            localStorage.removeItem('user')
        }
    }
})

export const userReducer = userSlice.reducer
export const { updateUser, clearUser } = userSlice.actions

store.ts

import { configureStore } from '@reduxjs/toolkit'
import {userReducer} from "./user/userSlice"

export const makeStore = () => {
  return configureStore({
    reducer: {user: userReducer}
  })
}

export type AppStore = ReturnType<typeof makeStore>
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']
     
Hidden answered 9/1 at 17:21 Comment(2)
I'm having the same issue, but in Chrome development only. If I run the app in Chrome as production, no error, and Edge and Firefox do not present this issue in either case. In Chrome dev only, the error isn't coming from app/layout.js. It's coming from .next/static/chunks/app/layout.js. It seems that there's a tailwindcss conflict. If I comment out tailwindcss: {} in postcss.config.js, there's no issue. Are you also using tailwind?Pogonia
I have a similar issue. Error happens in layout.js, it says Invalid or unexpected token. My environment is next.js, typescript, material-tailwind. when I comment out <ThemeProvider> component that is covered <html> for using material-tailwind, error doesn't happen.Irrespective
R
2

I don't know if OP managed to fix his issue, but I was in the exact same situation today with Nextjs 14. It's a bare-bone Next App wrapped in a next-auth <SessionProvider> with RSC + client buttons for signIn/signOut.

On every npm run dev, even tho this error wasn't always explicitly showing, my application would pre-render the HTML structure without undergoing the hydration phase, making client interactions impossible.

I deleted .next cache and node_modules , reinstalled node_modules and added turbopack to my dev command : npm run dev --turbo.

It seems to have fixed it so far, if I don't update you it's probably fixed for good. If anyone has/had that problem and knows the WHY, please explain.

Rancor answered 9/6 at 17:30 Comment(0)
A
0

Recently I had similar problem, but now I've fixed it. My way for solving this problem is by covering every client component with Suspense like this

<Suspense fallback={<FallbackComponent />}>
  <YourClientComponent/>
</Suspense>

When I run my project again, the error was disappear.

Anatolia answered 17/5 at 12:5 Comment(0)
E
0

Actually it's happening because the layout is a server component and it renders all of the children inside it. We know it's server side rendered when we wrap the Storeprovider inside it. Next.js attempts to load the necessary JavaScript for the client component during the SSR phase. This can lead to a timing issue where the client-side chunk for the StoreProvider is not ready or accessible when the server is trying to render the layout, causing the ChunkLoadError.

I tried to reinstall the whole module again, but this works only for a while -not always. So I used different approach to only wrap the component which is CSR and did some customization in my store.js. Basically I pass the same store on every request for creating the store. Below is an example:

 <StoreProvider>
  <SomeClientComponent/>//client component provide every where you want to use it
</StoreProvider>

store.js:

let store;
export const makeStore = () => {
  if (store) {//conditional store creation only creating when its not existing
    return store;
  }
  store= configureStore({
    reducer: {
      Authenticator: AuthSlice,
    },
  });
  return store;
};
Elizabethelizabethan answered 22/8 at 7:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.