chrisdancee / react-ios-pwa-prompt

A native styled 'Add to Home Screen' React component for PWAs on iOS
react-ios-pwa-prompt.vercel.app
169 stars 39 forks source link

Does not work with SSR #32

Open shihfu opened 4 years ago

shihfu commented 4 years ago

I get a "ReferenceError: window is not defined" when I try to import PWAPrompt from 'react-ios-pwa-prompt';

I believe this an issue with SSR in next.js. Is it possible to execute deviceCheck() after the component has been mounted?

Thanks.

chrisdancee commented 4 years ago

Hi @shih-js, I can take a look at this tonight. It's not something I've looked into specifically, but I can certainly try what you've suggested. I'll try and test replicate the issue myself, but might be useful if you could test the changes after I've put a branch up. Thank you for reporting the issue also.

chrisdancee commented 4 years ago

Hi @shih-js,

Apologies for the delay. I have a PR up https://github.com/chrisdancee/react-ios-pwa-prompt/pull/35 which could do with testing if you have a chance. I think this may resolve the issue. We may need additional checks for the window object first to avoid errors, not too sure yet.

shihfu commented 4 years ago

Just tested out the new branch, I am still receiving the same "ReferenceError: window is not defined". Thanks for looking into this. Much appreciated.

chrisdancee commented 4 years ago

@shih-js Is there any chance you could push your project, or an isolated version of this error? I think stubbing window and navigator will work, but I could ideally do with a test scenario.

chrisdancee commented 4 years ago

I've updated the branch with a new solution. If this works however, I'll still need to get SSR working locally to do some testing before I can merge, just to check I've added the minimum viable solution (i.e is the mount necessary still?). Thanks.

shihfu commented 4 years ago

I'll give the new update a shot and if that doesn't work - I'll create a new git repo with the bare minimum to recreate the issue this weekend.

shihfu commented 4 years ago

https://github.com/shih-js/react-ios-pwa-prompt-test

hipstersmoothie commented 4 years ago

The main issue I see as to why this is happening is the use of webpack. I don't really think it's necessary to bundle components. Shipping js + esm results in a better experience.

chrisdancee commented 4 years ago

Hi @shih-js,

Apologies for leaving this so long, managed to grab some time this weekend. This probably isn't of any use to you anymore tbh, but in the latest version I've changed the Webpack target to Node. This doesn't allow SSR per se, but will allow dynamic importing within NextJS to load the component on the client only.

Based on the repo you posted, I did the following:

import React from "react";
import dynamic from "next/dynamic";

const PWAPrompt = dynamic(() => import("react-ios-pwa-prompt"), {
  ssr: false
});

class HomePage extends React.Component {
  render() {
    return (
      <>
        <span>Hello from Canada</span>
        <PWAPrompt timesToShow={50} permanentlyHideOnDismiss={false} />
      </>
    );
  }
}

export default HomePage;
kellenmace commented 4 years ago

For anyone coming across this thread, I ended up using React.lazy in my Gatsby app to lazily load this library on the client-side only, so it wouldn't affect SSR. Example:

import React, { Suspense } from "react"

const PWAPrompt = React.lazy(() => import("react-ios-pwa-prompt"))

function PWAInstallPrompt() {
  return (
    <Suspense fallback={null}>
      <PWAPrompt
        promptOnVisit={1}
        timesToShow={3}
        permanentlyHideOnDismiss={false}
      />
    </Suspense>
  )
}

export default PWAInstallPrompt

Then you can render the <PWAInstallPrompt /> component anywhere in your app.

Note that as of the date of the this comment, the React Suspense API is still 'experimental'.

jpalo commented 2 years ago

Couldn't get Suspense working with Gatsby SSR, so used https://github.com/gregberge/loadable-components instead.