remix: [Bug]: "Prop `href` did not match". when using tailwindcss
Which Remix packages are impacted?
-
remix(Remix core) -
create-remix -
@remix-run/architect -
@remix-run/cloudflare-workers -
@remix-run/dev -
@remix-run/express -
@remix-run/netlify -
@remix-run/node -
@remix-run/react -
@remix-run/serve -
@remix-run/server-runtime -
@remix-run/vercel
What version of Remix are you using?
1.0.6
What version of Node are you using? Minimum supported version is 14.
16.13.1
Steps to Reproduce
- create remix app.
- add tailwindcss from this guide https://remix.run/docs/en/v1/guides/styling#tailwind.
- add tailwind.css to app/root.tsx.
import styles from './tailwind.css'
export function links() {
return [{ rel: 'stylesheet', href: styles }]
}
- start dev server
Expected Behavior
No warning message appears on browser console
Actual Behavior
This warning message appears on console
Warning: Prop `href` did not match. Server: "/build/_assets/tailwind-DGHXG3YF.css" Client: "/build/_assets/tailwind-JUD5S62U.css"
at link
at Links (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:3042:7)
at head
at html
at Document (http://localhost:3000/build/root-WYXGDNDR.js:55:3)
at App
at RemixCatchBoundary (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:1476:10)
at RemixErrorBoundary (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:1415:5)
at RemixRoute (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:2905:3)
at Routes (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:2888:7)
at Router2 (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:457:21)
at RemixCatchBoundary (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:1476:10)
at RemixErrorBoundary (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:1415:5)
at RemixEntry (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:2785:12)
at RemixBrowser (http://localhost:3000/build/_shared/chunk-KOXENSZ3.js:3262:42)
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 7
- Comments: 24 (6 by maintainers)
Commits related to this issue
- Workaround for tailwind warning. See https://github.com/remix-run/remix/issues/896 — committed to digitalservicebund/grundsteuer by shrzaf 2 years ago
The strangest thing is that if you change the file name of
tailwind.css, the error disappears.Any time you change your dependent file (.css), you’ll get this error. Mainly because the esbuild version used by Remix isn’t properly generating the filename hash for the importing file.
root-abc123.js imports style-def456.css
after changing css file, it creates a file named style-xyz789.css, which is imported in root.js correctly, but the filename is the same root-abc123.js (same filename, different content). Since these files are cached forever, your server side (which uses the new css) and your client (which is still using the old version… since it’s been cached) is out of sync.
With that being said, the bug is fixed in latest esbuild, so hopefully it will be included in next remix release.
This is tracked and fixed in this esbuild issue https://github.com/evanw/esbuild/issues/1957
It looks like a bug in esbuild… looked up docs for Entry Names:
https://esbuild.github.io/api/#entry-names
I was able to repro even for static CSS file. Basically anytime you import an asset that generates a hash and you change that imported file, the bundle contains the new hash, but the route filename hash stays the same… definitely not what the docs say (which is it should have a hash of the output file, including all imports).
I think I figured out why we’re getting the error
Warning: Prop href did not match. Server: "/build/_assets/tailwind-UF2CZ54Y.css" Client: "/build/_assets/tailwind-GCIKYTPB.cssIt looks like when esbuild compiles the route file, it generates the hash based on the contents of the original source, not the bundled output. So if your root route imports the tailwind.css file from app, the source never changes. But the tailwind URL will change and will generate a bundle with the new file path, but with the SAME root hash! And since the /public/build folder is immutable, it will never download the new root file. 😱 The only way to work around this in dev, is to disable caching in your dev tools. But you can’t rely on that on production.
To reproduce, have a clean /public/build folder. Start your app and let it build. Then rename /public/build to /public/build-old. Now add a new Tailwind class to your route and save. Remix will rebuild, but if you compare both root.js files (build and build-old), you’ll see the filename stays the same even though the import for tailwind.css has changed.
Not sure if this is an esbuild bug (it doesn’t really say whether the hash is dependent on the source contents or the bundled contents).
it’s correct, although one more thing : it happened again to me even with the workaround. deleting
.cachedidn’t solve anything that time. but when I hard refresh my page, everything went fine again : I guess it was a browser cache “issue” !this works!
I don’t know enough what’s happening here to actually help fix this but the workaround I’ve been using is…
Update
package.json:Then update
root.jsx:In Dev Tools, Network Tab
seeing this issue a lot. hard refresh in dev fixes it.
try move
tailwind.cssintoapp/stylesby use commandI confirm this issue, however, it seems more like a cache issue only. For anyone come across this issue, deleting
.cachefolder and re-run the server will fix the issue.There is indeed this problem. Turning on disable cache can temporarily eliminate the warning.