import React, { useEffect, useState } from 'react'; import '../styles/globals.css'; import App, { AppInitialProps, AppProps } from 'next/app'; import { SWRConfig } from 'swr'; import { ToastProvider } from 'react-toast-notifications'; import { parseCookies, setCookie } from 'nookies'; import Layout from '../components/Layout'; import { UserContext } from '../context/UserContext'; import axios from 'axios'; import { User } from '../hooks/useUser'; import { IntlProvider } from 'react-intl'; import { LanguageContext, AvailableLocales } from '../context/LanguageContext'; import Head from 'next/head'; import Toast from '../components/Toast'; const loadLocaleData = (locale: string) => { switch (locale) { case 'ja': return import('../i18n/locale/ja.json'); default: return import('../i18n/locale/en.json'); } }; // Custom types so we can correctly type our GetInitialProps function // with our combined user prop // This is specific to _app.tsx. Other pages will not need to do this! type NextAppComponentType = typeof App; type MessagesType = Record; interface ExtendedAppProps extends AppProps { user: User; messages: MessagesType; locale: AvailableLocales; } if (typeof window === 'undefined') { global.Intl = require('intl'); } const CoreApp: Omit = ({ Component, pageProps, router, user, messages, locale, }: ExtendedAppProps) => { let component: React.ReactNode; const [loadedMessages, setMessages] = useState(messages); const [currentLocale, setLocale] = useState(locale); useEffect(() => { loadLocaleData(currentLocale).then(setMessages); setCookie(null, 'locale', currentLocale, { path: '/' }); }, [currentLocale]); if (router.pathname.match(/(login|setup)/)) { component = ; } else { component = ( ); } return ( axios.get(url).then((res) => res.data), }} > Overseerr {component} ); }; CoreApp.getInitialProps = async (initialProps) => { const { ctx, router } = initialProps; let user = undefined; let locale = 'en'; if (ctx.res) { try { // Attempt to get the user by running a request to the local api const response = await axios.get( `http://localhost:${process.env.PORT || 3000}/api/v1/auth/me`, { headers: ctx.req ? { cookie: ctx.req.headers.cookie } : undefined } ); user = response.data; if (router.pathname.match(/login/)) { ctx.res.writeHead(307, { Location: '/', }); ctx.res.end(); } } catch (e) { // If there is no user, and ctx.res is set (to check if we are on the server side) // _AND_ we are not already on the login or setup route, redirect to /login with a 307 // before anything actually renders if (!router.pathname.match(/(login|setup)/)) { ctx.res.writeHead(307, { Location: '/login', }); ctx.res.end(); } } const cookies = parseCookies(ctx); if (!!cookies.locale) { locale = cookies.locale; } } // Run the default getInitialProps for the main nextjs initialProps const appInitialProps: AppInitialProps = await App.getInitialProps( initialProps ); const messages = await loadLocaleData(locale); return { ...appInitialProps, user, messages, locale }; }; export default CoreApp;