Prevent re-fetching resource after pageload with SSR setup

I have a resouce that I'm fetching in an SSR application.
export function getRawArticle() {
return createResource<RawArticle | null>( async () => {
const slug = createSlug();

if (import.meta.env.SSR) {
try {

return await getOrCreateArticle(slug)
} catch(e) {
console.error(e);
return null
}
} else {
return await getArticle(slug);
}
}, {
name: "article",
deferStream: true
})
}
export function getRawArticle() {
return createResource<RawArticle | null>( async () => {
const slug = createSlug();

if (import.meta.env.SSR) {
try {

return await getOrCreateArticle(slug)
} catch(e) {
console.error(e);
return null
}
} else {
return await getArticle(slug);
}
}, {
name: "article",
deferStream: true
})
}
So what this does is on the server side, if this resource is accessed, it checks firestore and if a document with the slug doesn't exist, it creates one, returning it. On the client-side, I don't want to write to the firestore, so if I fetch there, I only try reading, and if it doesn't exist, the resource returns null. I'm rendering this app on the server with renderToStringAsync, so I'd expect it to wait for the resource to load. However, when I load the page, the resource's contents don't seem to be there. I can see from logs that the fetch happens successfully on the server, but also that the fetcher is called again on the client. The problem is that firebase doesn't reflect the write yet, so it doesn't find the document. What could I be missing? Could it be that this null value from the client fetcher result is overwriting the value returned by the fetcher on the server-side? Is there a way I can prevent it from being re-fetched client side if we already have a value from SSR? For completeness sake, here's the component where I'm using it:
export default function App() {
const [ar, _actions] = getRawArticle()


return <>
<h1>{ar()?.title}</h1>
<div innerHTML={ar()?.body}></div>
</>
}
export default function App() {
const [ar, _actions] = getRawArticle()


return <>
<h1>{ar()?.title}</h1>
<div innerHTML={ar()?.body}></div>
</>
}
1 Reply
bigblind
bigblind4mo ago
Nevermind, solved it. I needed to wrap my use of ar() in a <Suspense>.