capacitor-community / apple-sign-in

Sign in with Apple Support
MIT License
135 stars 58 forks source link

SSR breaks the library on Nuxt 3 (`document is not defined`) #96

Open mateo-m opened 1 year ago

mateo-m commented 1 year ago

Describe the bug We are trying to use this plugin in an SSR web app built with Nuxt 3 and deployed to Cloudflare Pages. This library seems to rely on a dependency called ScriptJS which relies on document, which isn't defined when the page is served to the end user.

Here's the line that seems to break the library: https://github.com/capacitor-community/apple-sign-in/blob/6c86981ae26e33416bf7bd7bd5a3eb3983231bdb/src/web.ts#L2

Here's the full log of the error:

[mf:err] ReferenceError: document is not defined
    at definition (/private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:12:13)
    at ZV (/private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:8:72)
    at /private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:11:2
    at SourceTextModule.evaluate (node:internal/vm/module:226:23)
    at VMScriptRunner.runAsModule (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/runner-vm/src/index.ts:40:18)
    at VMScriptRunner.run (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/runner-vm/src/index.ts:86:17)
    at EventTarget.#reload (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/core/src/index.ts:790:13)
    at EventTarget.getPlugins (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/core/src/index.ts:1033:5)
    at createServer (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/http-server/src/index.ts:362:19)
    at startServer (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/http-server/src/index.ts:469:18)

/private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:12
  var doc = document
            ^
ReferenceError: document is not defined
    at definition (/private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:12:13)
    at ZV (/private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:8:72)
    at /private/Users/user/Documents/project-nuxt3/dist/Users/user/Documents/project-nuxt3/node_modules/scriptjs/dist/script.js:11:2
    at SourceTextModule.evaluate (node:internal/vm/module:226:23)
    at VMScriptRunner.runAsModule (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/runner-vm/src/index.ts:40:18)
    at VMScriptRunner.run (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/runner-vm/src/index.ts:86:17)
    at EventTarget.#reload (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/core/src/index.ts:790:13)
    at EventTarget.getPlugins (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/core/src/index.ts:1033:5)
    at createServer (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/http-server/src/index.ts:362:19)
    at startServer (/Users/user/Documents/project-nuxt3/node_modules/@miniflare/http-server/src/index.ts:469:18)
Waiting for the debugger to disconnect...

To Reproduce Steps to reproduce the behavior:

  1. Create a Nuxt 3 project.
  2. Install the library.
  3. Run the following script to build the project and run a local Wrangler server: "localwrangler": "NITRO_PRESET=cloudflare-pages npx nuxi build && npx wrangler pages dev dist/" (more information here: https://developers.cloudflare.com/workers/wrangler/commands/#dev).
  4. See the error I mentioned on the bug description.

Expected behavior If the library is used in a web app, it shouldn't have to forcibly rely on document as some apps might not be served as SPAs or rendered on the client-side.

Desktop (please complete the following information): This doesn't really matter because the web app simply doesn't run, but I'll fill it as the template asks for this information.

Additional context We made a quick hotfix consisting in a Nuxt plugin forcing this library to be loaded/rendered on the client-side, which always has a defined document.

Here's the code for it:

  1. Create a client-side plugin:
    
    import { SignInWithApple } from '@capacitor-community/apple-sign-in';

export default defineNuxtPlugin(() => { return { provide: { SignInWithApple, }, }; });

2. Add the plugin inside the component you want to use it in:

const { $SignInWithApple } = useNuxtApp();

3. Use the plugin inside the sign in method:

const signInApple = async () => { try { const { response } = await ($SignInWithApple as any).authorize({ clientId: import.meta.env.VITE_APPLE_CLIENT_ID, redirectURI: import.meta.env.VITE_API_URL, });

const data = await loginApi.signInApple({
  token: response.identityToken,
});

} catch (error) { console.log(error); } };