Home / Article Detail

Next.js 13 Page Route Interception

📅 Jan 13, 2025✍️ lllomh
    import React from 'react';
    import { createCache, extractStyle, StyleProvider } from '@ant-design/cssinjs';
    import Document, { Head, Html, Main, NextScript } from 'next/document';
    import type { DocumentContext } from 'next/document';
    import { parse } from 'cookie';

    const MyDocument = () => (
    <Html lang="ja">
    <Head>
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
    <link rel="shortcut icon" href="/favicon.ico" />
    <link rel="stylesheet" href="https://use.typekit.net/ucv8pdz.css" />
    <link href="https://fonts.cdnfonts.com/css/new-york-extra-large" rel="stylesheet" />
    </Head>
    <body>
    <Main />
    <NextScript />
    </body>
    </Html>
    );

    const whiteListedRoutes = ['/public', '/member/account', '/contact']; // Whitelisted routes

    MyDocument.getInitialProps = async (ctx: DocumentContext) => {
    const cache = createCache();
    const originalRenderPage = ctx.renderPage;
    ctx.renderPage = () =>
    originalRenderPage({
    enhanceApp: (App) => (props) => (
    <StyleProvider cache={cache}>
    <App {...props} />
    </StyleProvider>
    ),
    });

    const initialProps = await Document.getInitialProps(ctx);
    const style = extractStyle(cache, true);

    const cookies = parse(ctx.req.headers.cookie || '');
    const isAuthenticated = cookies['U_S'] !== undefined ? true : false;

    // Get the current route
    const currentRoute = ctx.pathname;

    console.log(currentRoute, 'currentRoute');
    console.log(isAuthenticated, 'isAuthenticated');

    // Check if the current route is in the whitelist
    const isRouteInWhiteList = whiteListedRoutes.includes(currentRoute);

    if (!isAuthenticated && isRouteInWhiteList) {
    console.log(4444);
    ctx.res.writeHead(302, { Location: '/member/login' });
    ctx.res.end();
    }

    return {
    ...initialProps,
    styles: (
    <>
    {initialProps.styles}
    <style dangerouslySetInnerHTML={{ __html: style }} />
    </>
    ),
    };
    };

    // Single export default function (Index)
    export default function Index({ authStates }: { authStates: boolean }) {
    // Logic for the Index page
    return (
    <div>
    <h1>Welcome to the Index page</h1>
    {authStates ? <p>You are authenticated</p> : <p>You are not authenticated</p>}
    </div>
    );
    }

    // Multiple export default function (Page)
    export function Page({ authStates, data }: { authStates: boolean; data: any[] }) {
    // Logic for the Page component
    return (
    <div>
    <h1>Page Data</h1>
    {authStates ? <p>You are authenticated</p> : <p>You are not authenticated</p>}
    <ul>
    {data.map((item, index) => (
    <li key={index}>{item}</li>
    ))}
    </ul>
    </div>
    );
    }

    export default MyDocument;