twind
twind copied to clipboard
Extract doesn't seem to work properly in SSR context with custom hash function
This is what I think is going on:
- We are using a custom
hash
function in our twind config (with tailwind preset, in case that's relevant). Amongst other things, it adds a prefix to all of the tailwind classnames. - Our app renders on the server (via nextjs), so the HTML that is passed to the
extract
function has classnames in it that have already been prefixed. - The
extract
process seems to expect the classnames in the markup to not already have been prefixed, so it does not identify any of them as relevant, and thus does not include the relevant css during extraction.
Can simulate this issue via the little test below:
// packages/twind/src/tests/extract.test.ts
test.only('custom hash function', () => {
const PREFIX = 'pr'
const tw = twind(
{
presets: [presetTailwind({ disablePreflight: true })],
hash: (className, defaultHash) => {
return `${PREFIX}-${className}`
},
},
virtual(),
)
const { html, css } = extract(
`
<div class="pr-flex h-screen">
Hello!
</div>
`,
tw,
)
// Note that this DOES pass, and is just here to demonstrate. twind matched the non-prefixed h-screen classname. In reality though, when using a hash function, these classes would already be "hashed" (prefixed in our case) when rendered on the server, prior to passing the rendered markup to extract.
assert.match(css, /pr-h-screen/)
// this assertion fails. I would expect the assertion above to fail, and this one to pass
assert.match(css, /pr-flex/)
})
I found the same issue on a recent project. I think I have a solution for this. I need to double check and will include a fix in the next release.
Thank you! Ping me if ya need any extra testing or anything.
Hey @marbemac, sorry it took me so long. Just to recap:
- you write "normal" tailwind classes
- these are passed to tw and your hash method adds a prefix
- extract (eg the second or another tw) expects "normal" tailwind classes and therefore does not find the prefixed/hashed ones
Twind had a bug where styles and classes are cleared from the internal tw sheet by extract before it parses the HTML. Meaning your already prefixed styles would not appear in the stylesheet. That bug has been fixed and your prefixed styles should now be within the stylesheet.
No problem - and yup! That's generally the issue as far as I can tell.
Unfortunately I'm not sure that it's fixed? At least on next.38
the SSR'd version of my test page still doesn't include the relevant CSS (when using custom hash function) and the assert.match(css, /pr-flex/)
test assertion in the PR description still fails when I run that test locally on next.38.
Hey folks. This issue hasn't received any traction for 90 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it. ⓘ
Hey folks. This issue hasn't received any traction for 90 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it. ⓘ