💎 Try Recall with a 7 day free trial!
August 22, 2022
Created using Midjourney - "japanese worker getting stressed in the office, black clothes, office setting, high stakes, monotone, high detail, 8k, --q 2 --ar 16:9"
Creating this blog section should be easy, right?
Well, here’s what happened:
The project is built on Next.js. It just happened that I had code lying around on my personal website for my own blog. Easy copy paste job right? Unfortunately, because these pages will be pre-rendered by Next.js, there were some issues.
For one, the whole project is currently server rendered. One assumption was on
the environment variable. The code is relying on the fact that
ROOT_URL can be
found. The problem is that the variable is not built in. This is so that we can
change the variable without rebuilding the docker image. This is problematic
since that functionality will be broken. There’s also some guards preventing
this from happening.
After some thinking, I decided to remove that functionality. It just doesn’t bring enough benefit to offset the downside.
In the first place, how often am I going to change the
never. And a docker build is just a command away.
Recall uses GraphQL and Apollo for most of its queries. Getting it to work with SSR can be finicky. I use the next-with-apollo library to get this to play nicely.
All this was handled in the
_app.tsx file. For those that don’t know, changes
to this file is propagated to all your pages. Convenient if you have code that
needs to run everywhere.
Apollo was also initiated here. This suddenly became an issue since some pages will be SSR and some will be static. So what do we do with Apollo?
next-with-apollo's documentation, any page with
getDataFromTree will be SSR.
We can’t keep the logic in
_app.tsx anymore since we can’t change how that
renders depending on the page. Those that need SSR needs the
prop. Meanwhile, static page need them gone.
There are 2 options:
ApolloProviderwithout SSR. Then wrap another
ApolloProviderif we need the SSR capability (or the reverse). I tried it but there are issues with multiple provider when doing SSR.
I didn’t want to do the 3rd option. But I experimented with the first 2 along with other ideas. Those didn’t get anywhere. After a good night sleep, I decided to go ahead with it.
After some work, I did it! I just need to wrap a
on every page.
Each page can be rendered just fine when you open them directly. However,
navigating from a page to another page wasn’t working. Apollo complained that it
can’t find the
ApolloProvider . This is odd. But after debugging some more, I
decided that this is a lost cause.
So what now?
There was another option that dare not dream. Run another Next.JS instance. One for SSR, one for those that can be statically generated. I could redirect the request to the correct instance.
With no other options in mind, I started working on a proof of concept. It didn’t go well.
Running 2 next instance in a custom server was not a good fit. I don’t even want to think about all the other issues — having to write in the correct place, having to handle the routing. What about development built?
Maybe I could build and export one of it? But it was too much work.
I was devastated. All this work for nothing. Is it time to call it quits and revert everything?
New feature to come:— Michael Salim (@IamMichaelSalim) August 21, 2022
Me: Oh, I can just copy this from another project. It's a 1 hour job.
Also me: Proceeds to unravel an issue 3 levels deep and now wondering if I should find a new career.#buildinpublic
The fact that this “blog” exists means that something went well 🙂
I realized something:
I can’t get
_app.tsx to change. But what if i modify the
method to be smart instead? Then that page can stay the same.
Diving deep into the
I found this line.
We want Apollo to be SSR when it runs in the server. So I just need to add a check for that.
As if by magic. Everything is solved.
After all that… Just a single line to patch🤦🏻♂️. Ok, there's a few more lines but they were trivial :)
There must be something to learn out of this. Well, that’s up to you to get something out of this!
Maybe think before you code? Or perhaps don’t work during the weekend 😂. Or maybe don’t sleep at 5am 😶
Like this kind of content? Why not see the reason I started writing TinyLog