-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pre render LandingPage for SEO #115
base: develop
Are you sure you want to change the base?
Conversation
export function useSanity<T>( | ||
query: string, | ||
typeGuard: (data: unknown) => data is T | ||
): T | undefined | null { | ||
const [data, setData] = React.useState<T | undefined | null>(undefined); | ||
React.useEffect(() => { | ||
fetchSanity(query, typeGuard) | ||
.then(setData) | ||
.catch((ex) => { | ||
logError('There was an exception in this Sanity query:', query); | ||
logError(ex); | ||
setData(null); | ||
}); | ||
}, [query, typeGuard]); | ||
export function useSanity<T>(query: string, typeGuard: (data: unknown) => data is T) { | ||
const data = useAtomValue(dataFamily({ query, typeGuard })) as T | undefined | null; | ||
return data; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was the main culprit. useEffect
only runs client side, jotai's useAtom
runs server and client side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice job gil
i am not sure i understand the last part "jotai's useAtom runs server and client side."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jotai implements data fetching with suspense see here: https://dev.to/smitterhane/swap-out-useeffect-with-suspense-for-data-fetching-in-react-2leb
Suspense approach(Render-as-You-Fetch).
Suspense for Data Fetching is a new feature. It lets you also use <React.Suspense> to declaratively "wait" for anything else, including data. In this article, we focus on the data fetching use case, but it can also wait for images, scripts, or other asynchronous work.
With Suspense, we don’t wait to render before we can start fetching. In fact, we kick off the network request(fetching) and immediately start rendering
Which means when you use useAtom
the content gets fetched in the body on the function not in an effect
, therefore it runs during SSR.
Basically we get SSR by merely using atoms instead of fetching in useEffect. (Except where we use sessionAtom
because nextAuth uses an effect internally to store the session, so we lose the benefit, but that's another story).
Downside is we fetch the data twice, once during SSR and again on the client, in the future we could refactor this to fetch in a RSC and pass to the client in props so we avoid double fetching.
Currently the LandingPage fetches the content from sanity on the client, which means it's not getting pre-rendered which is not optimal for SEO.
To check this try disabling javascript on your browser and open the app on

develop
branchNo content gets displayed other than the menu and footer which are rendered in server components.
Switch to this branch and reload.
Text renders for that SEO benefit.