QuiiBz / next-international

Type-safe internationalization (i18n) for Next.js
https://next-international.vercel.app
MIT License
1.26k stars 59 forks source link

Broken Hot Reload and massive hydration errors #418

Open lp1641 opened 1 month ago

lp1641 commented 1 month ago

Describe the bug

My next config.


/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/i,
      use: [
        {
          loader: '@svgr/webpack',
          options: {
            ref: true,
          },
        },
      ],
    });

    return config;
  },
  experimental: {
    turbo: {
      rules: {
        '*.svg': {
          loaders: [
            {
              loader: '@svgr/webpack',
              options: {
                ref: true,
              },
            },
          ],
          as: '*.js',
        },
      },
    },
  },
  reactStrictMode: true,
  typescript: {
    ignoreBuildErrors: true,
  },
  compiler: {
    styledComponents: true,
  },
  images: {
    remotePatterns: [
      { hostname: 'localhost' },
      { hostname: '46.101.124.210', port: '4300' },
      { hostname: 'cloudflare-ipfs.com' },
    ],
  },
};

const millionConfig = {
  auto: {
    // threshold - What is used to determine whether a component should be converted to Million.js.
    // When the threshold increases, fewer components will be optimized, and vice versa.
    threshold: 0.05, // default: 0.1,
    // skip - An array of identifiers to indicate if a component should be skipped. You can add hook or variable names, function names, etc.
    skip: [], // 'useBadHook', /badVariable/g
    // if you're using RSC: auto: { rsc: true },
  },
};

export default million.next(nextConfig, millionConfig);

My package json. I have another one at a higher level where there are more libraries. But this should be enough.

  "dependencies": {
    "million": "^3.0.6",
    "next": "^14.2.5",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-to-print": "^2.15.1"
  },
  "devDependencies": {
    "sharp": "^0.33.4",
    "typescript": "^5.5.4",
    "@types/node": "^20.14.12",
    "@svgr/webpack": "^8.1.0",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "eslint": "^9.7.0",
    "eslint-config-next": "^14.2.5"
  }

To Reproduce Use useScopedI18n and I18nProviderClient in the root layout of your project. You will see a bunch of errors in the Network logs and also on every hot reload refresh there will be an error forcing a full page refresh. It looks like the language file fails to load in time and a hydratation error occurs, the problem is that this greatly hinders local development because it breaks hot reload. If you build the project, then everything will be fine because everything will be rendered in advance if you use generateStaticParams in the root layout. I used millionjs and turbopack with the start parameter "next dev --turbo" but these errors repeat without millionjs and turbopack. I use also svgr and styled components in my project.

Expected behavior I expected there wouldn't be any of these errors.

Screenshots Massive errors about sourcemaps. image image

Example:

http://localhost:3200/__nextjs_original-stack-frame?isServer=false&isEdgeServer=false&isAppDirectory=true&errorMessage=Error%3A+Hydration+failed+because+the+initial+UI+does+not+match+what+was+rendered+on+the+server.%0ASee+more+info+here%3A+https%3A%2F%2Fnextjs.org%2Fdocs%2Fmessages%2Freact-hydration-error&file=file%3A%2F%2FK%3A%2FProjects%2Fnx-nextjs-boilerplate%2Fapps%2Fadmin-panel%2F.next%2Fstatic%2Fchunks%2F08b5e_next_dist_compiled_react-dom_cjs_react-dom_development_c9a189.js&methodName=throwOnHydrationMismatch&arguments=&lineNumber=6451&column=19
Request Method:
GET
Status Code:
404 Not Found

Response:
Unable to resolve sourcemap

Hot reload is broken. Each hot reload leads to following error: image

About (please complete the following information):

Additional context I don't know if there are any ways to solve this.

I tried removing I18nProviderClient from the code and replacing the useScopedI18n hook with a stub and the errors stopped. I was trying to check if it could be middleware or something else. Also, if only the hook is replaced with a stub, the errors will still occur because of the provider. So the problem is somewhere in the provider code in my opinion.

Root layout: apps\admin-panel\app[locale]\layout.tsx

// Intl
import { getStaticParams } from 'locales/server';

export function generateStaticParams() {
  return getStaticParams();
}

import { RootLayout } from 'modules/main/layouts/RootLayout';

export default RootLayout;

apps\admin-panel\modules\main\layouts\RootLayout\index.tsx

'use client';
import React from 'react';

// Styles
import { GlobalStyles } from '../GlobalStyles';

// UI
import { init } from '@ui/base-popup-messages';
import { ThemeProvider } from 'styled-components';
import { lightThemeWithPlugins } from 'shared/theme';

// Styled components SSR
import { StyledComponentsRegistry } from '@ui/react-stylizing-components';

// Fonts
import { Poppins } from 'next/font/google';

// React Query
import { QueryClientProvider, queryClient } from 'shared/libs/rest';

// Intl
import { I18nProviderClient } from 'locales/client';

// Layouts
import { BodyWrapper } from '../BodyWrapper';

const poppins = Poppins({
  preload: true,
  subsets: ['latin'],
  weight: ['400', '600', '700'],
});

// Connect popup messages to the root layout
const { ToastContainer } = init();

// Types
export interface RootLayoutProps {
  params: { locale: string };
  children: React.ReactNode;
}

export const RootLayout = ({
  params: { locale },
  children,
}: RootLayoutProps) => {
  return (
    <I18nProviderClient locale={locale}>
      <QueryClientProvider client={queryClient}>
        <StyledComponentsRegistry>
          <ThemeProvider theme={lightThemeWithPlugins}>
            <html className={poppins.className} lang={locale}>
              <GlobalStyles />
              <head>
                <meta charSet="utf-8" />
                <meta
                  name="viewport"
                  content="width=device-width, initial-scale=1, maximum-scale=1"
                />
                <meta name="next-head-count" content="2" />
                <link rel="icon" type="image/x-icon" href="/images/logo.svg" />
              </head>
              <BodyWrapper>
                {children}
                <ToastContainer />
              </BodyWrapper>
            </html>
          </ThemeProvider>
        </StyledComponentsRegistry>
      </QueryClientProvider>
    </I18nProviderClient>
  );
};

Can I wait for language files to be imported first and then render the UI? Perhaps the reason for the error is that the interface is rendered first without the language file and then with it.

image

lp1641 commented 1 month ago

UPD:

If I use

fallback={<>fff</>}

First I see for a brief moment the content of the page and then everything is white.

image

lp1641 commented 1 month ago

UPD 2: I tried 1.1.4 version and there was same thing.

Then downgraded. 1.0.1 - at first glance works ok. It doesn't break my project. But now I'm noticing the flickering text when the page is displayed. 1.1.0 - at first glance works ok, no flickering. But have this error when go back from other page. I have 'use client'; at my root layout so that's strange. image And then after several moves between pages I got this and stuck, even page reload doesn't help. image

1.1.1 - errors appears like at latest version