AxaFrance / oidc-client

Light, Secure, Pure Javascript OIDC (Open ID Connect) Client. We provide also a REACT wrapper (compatible NextJS, etc.).
MIT License
597 stars 160 forks source link

"ReferenceError: navigator is not defined" error when page is first time accessed in Next.js #853

Closed ryanelian closed 2 years ago

ryanelian commented 2 years ago

Issue and Steps to Reproduce

Setup _app.tsx in Next.js like below:

function CustomApp({
    Component,
    pageProps
}: AppPropsWithLayout): JSX.Element {

    const router = useRouter()
    const withCustomHistory = () => {
        return {
            replaceState: (url: string) => {
                router.replace({
                    pathname: url,
                }).then(() => {
                    window.dispatchEvent(new Event('popstate'));
                });
            }
        };
    };

    const withLayout = Component.layout ?? (page => page);
    return (
        <OidcProvider withCustomHistory={withCustomHistory} configuration={{
            authority: '...',
            client_id: '...',
            redirect_uri: '...',
            silent_redirect_uri: '...',
            scope: 'openid profile email offline_access',
        }}>
            {withLayout(<Component {...pageProps} />)}
        </OidcProvider>
    );
}

Run the page in browser.

Versions

6.5.5

Screenshots

image

Expected

No errors

Actual

[dev:nextjs] error - unhandledRejection: ReferenceError: navigator is not defined
[dev:nextjs]     at D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\initWorker.js:111:17
[dev:nextjs]     at step (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\initWorker.js:33:23)
[dev:nextjs]     at Object.next (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\initWorker.js:14:53)
[dev:nextjs]     at D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\initWorker.js:8:71
[dev:nextjs]     at new Promise (<anonymous>)
[dev:nextjs]     at __awaiter (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\initWorker.js:4:12)
[dev:nextjs]     at initWorkerAsync (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\initWorker.js:106:87)
[dev:nextjs]     at Oidc.<anonymous> (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\oidc.js:617:87)
[dev:nextjs]     at step (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\oidc.js:59:23)
[dev:nextjs]     at Object.next (D:\VS\accelist-nextjs-starter\node_modules\@axa-fr\react-oidc\dist\vanilla\oidc.js:40:53)

Additional Details

Suspected that this function errored when the page is first accessed on server-side https://github.com/AxaGuilDEv/react-oidc/blob/master/packages/react/src/oidc/vanilla/initWorker.ts#L69

navigator is only available at browser and not during SSR.

Next.js 12.3

guillaume-chervet commented 2 years ago

Hi @ryanelian , thank you very much for your issue. Do you know what i have to do to activate Ssr on the demo? https://github.com/AxaGuilDEv/react-oidc/tree/master/packages/nextjs-demo Do you have possibility fork and show me? I am a noob with nextjs and very busy this month.

ryanelian commented 2 years ago

Hi @ryanelian , thank you very much for your issue. Do you know what i have to do to activate Ssr on the demo? https://github.com/AxaGuilDEv/react-oidc/tree/master/packages/nextjs-demo Do you have possibility fork and show me? I am a noob with nextjs and very busy this month.

Hi, thanks for replying.

I believe doing this in _app.tsx will disable Automatic Static Optimization in all pages (and forces all pages to use SSR): https://github.com/accelist/nextjs-starter/blob/master/pages/_app.tsx#L38-L45

// This disables the ability to perform Automatic Static Optimization... (Sadge)
// Causing every page in the app to be server-side rendered,
// but allowing the use of runtime configuration in Docker-based Environment!
CustomApp.getInitialProps = async (appContext: AppContext) => {
    // calls page's `getInitialProps` and fills `appProps.pageProps`
    const appProps = await App.getInitialProps(appContext);
    return { ...appProps };
}

If you simply wish to observe the error, I have prepared a special branch for you:

https://github.com/accelist/nextjs-starter/tree/openid-react-issue853

https://github.com/accelist/nextjs-starter/archive/refs/heads/openid-react-issue853.zip

Simply clone / download the branch and run npm run dev then access http://localhost:3000 to observe the error

ryanelian commented 2 years ago

I just confirmed that the issue exists on demo project when SSR is enabled app-wide:

image

Fork: https://github.com/ryanelian/react-oidc

Compare: https://github.com/AxaGuilDEv/react-oidc/compare/master...ryanelian:react-oidc:master

SSR Documentation: (Supported use case) https://nextjs.org/docs/advanced-features/custom-app

guillaume-chervet commented 2 years ago

Awesome @ryanelian , thank you, I test it right now !

guillaume-chervet commented 2 years ago

I can reproduce the error thank you very much :)

guillaume-chervet commented 2 years ago

Last version 6.5.7 seem to resolve the problem (I'am not sure @ryanelian ). image