torchlight-api / torchlight-cli

Node CLI for Torchlight
15 stars 2 forks source link

usage with nextjs #6

Closed mcgrealife closed 1 year ago

mcgrealife commented 1 year ago

An interesting challenge!

During next build, next transforms JSX into optimized HTML and JS files.

So, in the torchlight config file, for the input, I provided the pathway to the files output by nextjs.

Run yarn next built && yarn torchlight (or simply add a "postbuild": "yarn torchlight")

And I can see that torchlight has transformed the HTML files that were output by nextjs!

So I deploy the code and open in browser.

On initial paint, the torchlight modified HTML is shown - and it's beautiful! But then, nextjs tries to hydrate the html with the associated js file, and a hydration error is thrown. Because even though torchlight modified the html files, it did not also modify the associated next js files.

To emphasize: if I disable javascript in the browser, the beautiful torchlit HTML is displayed. The problem is that the js file generated by nextjs does not match the HTML file when using torchlight like this.

I'm trying to find a way to hook into the next build process, so that the torchlight command can be run after next build generates html files, but before it generates js files. So that next can generate JS files using the modified HTML. But I'm guessing it wouldn't work because nextjs likely generates js files based on the source jsx file (not the html file). Maybe the solution is a nextjs swc plugin (or a now legacy babel plugin). NextJS does support MDX with Remark and Rehype, so maybe https://github.com/torchlight-api/remark-torchlight is the best solution.

mcgrealife commented 1 year ago

Final for nextjs:

I couldn't find a way to hook into nextJs's build process after react-dom/server converts jsx to HTML and before nextjs creates the associated javascript file (which react uses to 'rehydrate' the client). Therefore, unless the site has javascript disabled, the highlighted HTML shown on first paint will be overwritten by the HTML that react re-creates using the javascript instructions file.

One alternate way to modify the HTML before next build gets it is via the torchlight remark plugin. It feels strange to use mdx just for it's unified rehype tooling. Especially because this solution requires passing the remark output back to jsx using the dangerouslySetInnerHTML prop. But it definitely works!