import type { ReactElement, ReactNode } from 'react'; import React, { useEffect } from 'react'; import type { Locale } from '@growi/core'; import type { NextPage } from 'next'; import { appWithTranslation } from 'next-i18next'; import type { AppContext, AppProps } from 'next/app'; import App from 'next/app'; import { useRouter } from 'next/router'; import { SWRConfig } from 'swr'; import * as nextI18nConfig from '^/config/next-i18next.config'; import { GlobalFonts } from '~/components/FontFamily/GlobalFonts'; import type { CrowiRequest } from '~/interfaces/crowi-request'; import { useAppTitle, useConfidential, useGrowiVersion, useSiteUrl, useIsDefaultLogo, useForcedColorScheme, } from '~/stores-universal/context'; import { swrGlobalConfiguration } from '~/utils/swr-utils'; import { getLocaleAtServerSide, type CommonProps } from './utils/commons'; import '~/styles/prebuilt/vendor.css'; import '~/styles/style-app.scss'; import { registerTransformerForObjectId } from './utils/objectid-transformer'; // eslint-disable-next-line @typescript-eslint/ban-types export type NextPageWithLayout

= NextPage & { getLayout?: (page: ReactElement) => ReactNode, } type GrowiAppProps = AppProps & { Component: NextPageWithLayout, userLocale: Locale, }; // register custom serializer registerTransformerForObjectId(); function GrowiApp({ Component, pageProps, userLocale }: GrowiAppProps): JSX.Element { const router = useRouter(); useEffect(() => { const updateLangAttribute = () => { if (document.documentElement.getAttribute('lang') !== userLocale) { document.documentElement.setAttribute('lang', userLocale); } }; router.events.on('routeChangeComplete', updateLangAttribute); return () => { router.events.off('routeChangeComplete', updateLangAttribute); }; }, [router, userLocale]); useEffect(() => { import('bootstrap/dist/js/bootstrap'); }, []); const commonPageProps = pageProps as CommonProps; useAppTitle(commonPageProps.appTitle); useSiteUrl(commonPageProps.siteUrl); useConfidential(commonPageProps.confidential); useGrowiVersion(commonPageProps.growiVersion); useIsDefaultLogo(commonPageProps.isDefaultLogo); useForcedColorScheme(commonPageProps.forcedColorScheme); // Use the layout defined at the page level, if available const getLayout = Component.getLayout ?? (page => page); return ( <> {getLayout()} ); } GrowiApp.getInitialProps = async(appContext: AppContext) => { const appProps = App.getInitialProps(appContext); const userLocale = getLocaleAtServerSide(appContext.ctx.req as unknown as CrowiRequest); return { ...appProps, userLocale }; }; export default appWithTranslation(GrowiApp, nextI18nConfig);