vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.37k stars 26.78k forks source link

Wrong warning "You have opted-out of Automatic Static Optimization due to getInitialProps in pages/_app" #27270

Closed AbdUlHamedMaree closed 3 years ago

AbdUlHamedMaree commented 3 years ago

What version of Next.js are you using?

11.0.1

What version of Node.js are you using?

14.16.1

What browser are you using?

Chrome

What operating system are you using?

Windows

How are you deploying your application?

next start

Describe the Bug

my project is so simple, but I face this problem where a wrong warning about using getInitialProps in pages/_app, I didn't use getInitialProps in _app and the _app exported with no HOC, this warning followed by all pages being SSR, so no SEO and to static optimization features, my _app is so large 😊but you can clearly see that I'm not using getInitialProps or a HOC.

_app.tsx

import Head from 'next/head';
import { AppProps, NextWebVitalsMetric } from 'next/app';
import React, { useState } from 'react';
import { QueryClientProvider } from 'react-query';
import { AnimateSharedLayout } from 'framer-motion';
import { ToastContainer, Slide } from 'react-toastify';
import CssBaseline from '@material-ui/core/CssBaseline';
// import { ReactQueryDevtools } from 'react-query/devtools';

import 'react-toastify/dist/ReactToastify.min.css';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';

import {
  MainLayout,
  MuiThemeProvider,
  GlobalStyles,
  RTL,
  SplashScreen,
} from '@/components';
import { queryClient } from '@/config';

import { LocalizationProvider } from '@material-ui/lab';
import AdapterMoment from '@material-ui/lab/AdapterMoment';
import { FormBuilderProvider } from '@scandinavia/material-form-builder';
import { DefaultSeo } from 'next-seo';
import useTranslation from 'next-translate/useTranslation';
import { useMemo } from 'react';

const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => {
  const { lang } = useTranslation();
  const [initialized, setInitialized] = useState(false);
  const dir = useMemo(() => (lang === 'en' ? 'ltr' : 'rtl'), [lang]);
  React.useEffect(() => {
    setInitialized(true);
  }, []);

  if (!initialized) return <SplashScreen />;

  return (
    <>
      <DefaultSeo
        title='Lamar Aesthetic surgery Center | Your beauty is our duty'
        defaultTitle='La Mar Clinic'
        titleTemplate='%s | La Mar Clinic'
        description="Lamar Aesthetic surgery center offers you an unparalleled beauty experience from inside out. Discover Lamar clinic's wide array of facilities and services now."
        canonical='https://lamar-clinic.com'
        openGraph={{
          title: 'La Mar Clinic',
          type: 'website',
          description:
            "Lamar Aesthetic surgery center offers you an unparalleled beauty experience from inside out. Discover Lamar clinic's wide array of facilities and services now.",
          site_name: 'La Mar Clinic',
          url: 'https://www.lamar-clinic.com',
          images: [
            {
              url: 'https://www.lamar-clinic.com/assets/images/logo.png',
              alt: 'La Mar Logo',
            },
          ],
        }}
        facebook={
          process.env.NEXT_PUBLIC_FACEBOOK_ID
            ? { appId: process.env.NEXT_PUBLIC_FACEBOOK_ID }
            : undefined
        }
        twitter={{
          cardType: 'summary_large_image',
          site: 'La Mar Clinic',
        }}
        additionalMetaTags={[
          {
            name: 'og:image',
            content: 'https://www.lamar-clinic.com/assets/images/logo.png',
          },
        ]}
      />
      <Head>
        <meta name='viewport' content='initial-scale=1, width=device-width' />
      </Head>
      <QueryClientProvider client={queryClient}>
        <RTL direction={dir}>
          {/* <ReactQueryDevtools /> */}
          <MuiThemeProvider>
            <GlobalStyles />
            <CssBaseline />
            <LocalizationProvider dateAdapter={AdapterMoment}>
              <AnimateSharedLayout type='crossfade'>
                <FormBuilderProvider lang={lang as 'ar' | 'en'}>
                  <MainLayout>
                    <Component {...pageProps} />
                  </MainLayout>
                </FormBuilderProvider>
              </AnimateSharedLayout>
            </LocalizationProvider>
          </MuiThemeProvider>
        </RTL>
      </QueryClientProvider>
      <ToastContainer
        position={lang === 'en' ? 'top-right' : 'top-left'}
        autoClose={3500}
        hideProgressBar
        newestOnTop={false}
        closeOnClick
        rtl={lang === 'ar'}
        pauseOnFocusLoss
        draggable
        pauseOnHover
        limit={3}
        transition={Slide}
      />
    </>
  );
};
export default MyApp;

const get = (metric: NextWebVitalsMetric) => ({
  value: (metric.value / 1000)?.toFixed(4),
  startTime: (metric.startTime / 1000)?.toFixed(4),
});

export const reportWebVitals = (metric: NextWebVitalsMetric) => {
  let content: {
    name: string;
    value: string;
    startTime: string;
  } | null = null;
  switch (metric.name) {
    case 'FCP':
      content = {
        name: 'First Contentful Paint',
        ...get(metric),
      };
      break;

    case 'LCP':
      content = {
        name: 'Largest Contentful Paint',
        ...get(metric),
      };
      break;

    case 'CLS':
      content = {
        name: 'Cumulative Layout Shift',
        ...get(metric),
      };
      break;

    case 'FID':
      content = {
        name: 'First Input Delay',
        ...get(metric),
      };
      break;

    case 'TTFB':
      content = {
        name: 'Time to First Byte',
        ...get(metric),
      };
      break;

    case 'Next.js-hydration':
      content = {
        name: 'Length of time it takes for the page to start and finish hydrating',
        ...get(metric),
      };
      break;

    case 'Next.js-route-change-to-render':
      content = {
        name: 'Length of time it takes for a page to start rendering after a route change',
        ...get(metric),
      };
      break;

    case 'Next.js-render':
      content = {
        name: 'Length of time it takes for a page to finish render after a route change',
        ...get(metric),
      };
      break;

    default:
      content = {
        name: metric.name,
        ...get(metric),
      };
      break;
  }

  false &&
    !!content &&
    process.env.NODE_ENV !== 'production' &&
    console.table(content);
};

Expected Behavior

this warning to not appears in the console and all pages being SSG.

To Reproduce

create pages/_app with the same configuration and it will produce the problem

AbdUlHamedMaree commented 3 years ago

my next.config.js

// // @ts-check

// /**
//  * @type {import('next').NextConfig}
//  **/

// This file sets a custom webpack configuration to use your Next.js app
// with Sentry.
// https://nextjs.org/docs/api-reference/next.config.js/introduction
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

const { withSentryConfig } = require('@sentry/nextjs');
const nextTranslate = require('next-translate');

const moduleExports = nextTranslate({
  images: {
    domains: [
      // our domains
      'lamar-clinic.com',
      'www.lamar-clinic.com',
      'api.lamar-clinic.com',
      // mock domains
      'i.pravatar.cc',
      'picsum.photos',
    ],
  },
  reactStrictMode: true,
  distDir: 'build',
  webpack5: true,
  typescript: {
    ignoreBuildErrors: true,
  },
  eslint: {
    ignoreDuringBuilds: true,
  },
});

const SentryWebpackPluginOptions = {
  // Additional config options for the Sentry Webpack plugin. Keep in mind that
  // the following options are set automatically, and overriding them is not
  // recommended:
  //   release, url, org, project, authToken, configFile, stripPrefix,
  //   urlPrefix, include, ignore

  silent: true, // Suppresses all logs
  // For all available options, see:
  // https://github.com/getsentry/sentry-webpack-plugin#options.
};

// Make sure adding Sentry options is the last code to run before exporting, to
// ensure that your source maps include changes from all other Webpack plugins
module.exports = withSentryConfig(moduleExports, SentryWebpackPluginOptions);
ijjk commented 3 years ago

Hi, it looks like this might be being added by one of your plugins in your next.config.js as next-translate attempts to detect if it should leverage getInitialProps or not, can you try removing your custom configuration and seeing if the problem persists?

This seems unlikely to be caused by Next.js itself, if you are able to still be able to reproduce this after removing the custom plugins in your next.config.js please provide a link to a repo to allow further investigation!

balazsorban44 commented 2 years ago

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.