#ReferenceError: navigator is not defined

1 messages · Page 1 of 1 (latest)

rancid sand
#

My code is {navigator.canShare && <ShareButton /> }

normal jewel
# rancid sand My code is `{navigator.canShare && <ShareButton /> }`

Navigator does not exist on the server and certain browser providers (electron apps if I remember correct). If you’re only running in a browser and navigator should exist then you need to check that you’re currently in a hydrated state because remix on the server does not have a navigator item. You can do this by using sergiodxa’s remix utils to useHydrated or useClientOnly. Either of which should help you get it working

rancid sand
#

That's more complicated than i was expecting but thanks. I installed it.
I tried this code:

 <ClientOnly>                
    <ShareButton />
 </ClientOnly>

I am getting a very unhelpful error:

renderWithHooks@http://localhost:3000/build/entry.client-IWXTCWXB.js:11766:35
updateFunctionComponent@http://localhost:3000/build/entry.client-IWXTCWXB.js:14154:43
beginWork$1@http://localhost:3000/build/entry.client-IWXTCWXB.js:19251:31
performUnitOfWork@http://localhost:3000/build/entry.client-IWXTCWXB.js:18699:31
workLoopSync@http://localhost:3000/build/entry.client-IWXTCWXB.js:18635:30
renderRootSync@http://localhost:3000/build/entry.client-IWXTCWXB.js:18614:27
recoverFromConcurrentError@http://localhost:3000/build/entry.client-IWXTCWXB.js:18236:42
performConcurrentWorkOnRoot@http://localhost:3000/build/entry.client-IWXTCWXB.js:18184:56
performConcurrentWorkOnRoot@[native code]
workLoop@http://localhost:3000/build/entry.client-IWXTCWXB.js:200:50
flushWork@http://localhost:3000/build/entry.client-IWXTCWXB.js:179:30
performWorkUntilDeadline@http://localhost:3000/build/entry.client-IWXTCWXB.js:387:50
normal jewel
rancid sand
#

The docs say its recommended but not required

normal jewel
#

Yea

#

Just making sure you know about the fallback

rancid sand
#

If I build it and run start (rather than dev) I get this error. It's no more helpful though really:

TypeError: l is not a function
    at h (http://localhost:3000/build/routes/index-AODIA3WW.js:1:286)
    at mu (http://localhost:3000/build/entry.client-ZOIG5E4U.js:6:19484)
    at Pi (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:3153)
    at Xa (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:44792)
    at $a (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:39724)
    at Zf (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:39655)
    at br (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:39515)
    at Ui (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:35905)
    at Ha (http://localhost:3000/build/entry.client-ZOIG5E4U.js:8:34858)
    at Cl (http://localhost:3000/build/entry.client-ZOIG5E4U.js:1:1741)
#

I find the error messages in Remix are usually pretty terrible 🤷‍♂️

normal jewel
#

I don’t fully disagree. But I think it’s more of a SSR react is pretty new and not very well documented yet so there’s a lot of bleeding edge of tech pain. The is not a function is somewhat interesting because that to me means you might have a react component that isn’t well defined and it’s trying to call it but it’s not returning jsx sometimes. Idk if you’re using typescript or not but I believe a react component function needs to always return html even if it’s an empty fragment

#

Are you able to provide more code of what’s happening in share button or around that area? @rancid sand

rancid sand
#

My code:

  function ShareButton() {    if (navigator.canShare) {     return (      <button onClick={handleShare} className="button"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="feather feather-share-2"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg>Share</button>    )    } else {return null}  }
normal jewel
#

I’ve had many complaints in typescript saying “cannot be used as a JSX element because it doesn’t always return html” not exactly that, but that sort of idea. Try instead return <><>

#

<><>*

#

It keeps removing back slash but you get the idea lol

rancid sand
#

I've not been using Typescript, maybe I should. I now get the error TypeError: children is not a function

normal jewel
#

Ah, very interesting. And that’s happening in the clientOnly zone I’m guessing. There must be something strange going on with the share button component

rancid sand
#

I tried moving the logic

    <ClientOnly>
{ navigator.canShare && <ShareButton />}                </ClientOnly>
#

This is again giving me the navigator is not defined error 🤯 😿

normal jewel
#

Man, that navigator is really causing issues. Try one thing for me for sanity. UseHydrated instead and do something like:
Const hydrated = useHydrated()
{hydrated && navigator.canShare && <ShareButton/>

#

I typically useHydrated and do those kinda checks but usually with ternaries. clientOnly should be doing this under the hood but just in case some weird thing is happening with rendering

#

Sorry I can’t pretty format. On phone lol

rancid sand
#

Amazing. Thanks that worked! 🙂

normal jewel
#

So very strange clientOnly didn’t do the trick

rancid sand
#

It really shouldn't be this hard. Surely people need to use navigator all the time?

normal jewel
#

Eh, I’ve made a fairly large app and never touched the navigator lol

#

The window is more common

rancid sand
#

I might raise an issue in the utils project

normal jewel
#

On remix itself it recommends doing if(window){} so you can probably do the same with if(navigator){} I just know a lot of remix utils are pretty useful and usually are my preferred way of guaranteeing a window or other browser apis

#

useHydrated in particular has been super useful for me all through my app. Whereas always checking for windows and such feels less good to me

rancid sand
#

Oh I hadn't even thought of doing a conditional for navigator, that makes sense

normal jewel
#

I didn’t recommend the navigator check because I wasn’t sure if doing that one in particular. I haven’t seen any examples but in theory it should work just the same. Slightly sick so my brain isn’t fully there