SimeonGriggs / sanity-react-router-template

Sanity Studio v3 embedded into a Remix Vite application configured for Vercel hosting with visual editing
https://sanity-remix-template.sanity.build
164 stars 35 forks source link

Uncaught TypeError: Cannot read properties of undefined #2

Closed soderlind closed 2 years ago

soderlind commented 2 years ago

As I mentioned at https://github.com/sanity-io/sanity/discussions/3642#discussioncomment-3691813, I got the following error:

Uncaught TypeError: Cannot read properties of undefined (reading 'projectId')
    at config.ts:19:59

1 Should fix that.

soderlind commented 2 years ago

Not a problem, #3 was the sinner.

soderlind commented 2 years ago

:( it's still a problem

timbakkum commented 2 years ago

I am also playing around with this repo and using some of the code in my own project setup. It seems like the previous JS error caused client side JS/react to stop. That's why useState etc. didn't work. After the fix, it's probably the image builder trying to use the server side project details client side causing the problem. A similar fix is needed here. I'm doing something like:

export const imageUrlBuilder = urlBuilder(
  typeof window !== 'undefined' ? projectDetailsBrowser : projectDetails
);

This causes images to render server side and client side. Downside is that you have to put your sanity info on the window.ENV on every page (where you want to consume them), but for public datasets this is not an issue I think because the id and dataset name are in the url of your assets anyway if you are using the image builder urls or the urls that you get from the groq query.

however, what would be the approach when you start making your dataset private? would you need to create some kind of resource route to hide your access token behind and return a queried asset to your frontend? 🤔

SimeonGriggs commented 2 years ago

Making your projectId public is not considered a problem, even with a private dataset.

However on both Public and Private datasets, assets are always Public. This is documented.

There might be a better approach to making the whole app "aware" of the sanity config. I'll experiment.

soderlind commented 2 years ago

@timbakkum According to Remix gotchas, we shouldn't use window, but use documentinstead.

timbakkum commented 2 years ago

Making your projectId public is not considered a problem, even with a private dataset.

However on both Public and Private datasets, assets are always Public. This is documented.

There might be a better approach to making the whole app "aware" of the sanity config. I'll experiment.

Thanks for the info. 👍🏻 I am thinking for the simple product page you created, you can avoid the whole problem by just disabling hydration if you don't need JS for anything after SSR on that page (I am creating a blog, so no need to re-query the asset really). However, on more dynamic pages, you will run into the problem again. Would be nice to also see an example where an accessToken is needed.

SimeonGriggs commented 2 years ago

Right, so if you needed to keep querying data with a private dataset, you'd need that to be pulled in from the server-side – which Remix would handle for you. It's only once you're trying to use the Sanity Client, client side, that you'd have an issue.

You still want the projectId and dataset name in the browser's scope so things like image URLs can be generated.

I've updated the example to change how it looks up the config, and it writes the window.ENV values on every route – so images load on every SSR and CSR.