twind icon indicating copy to clipboard operation
twind copied to clipboard

Extract doesn't seem to work properly in SSR context with custom hash function

Open marbemac opened this issue 2 years ago • 4 comments

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/)
})

marbemac avatar Mar 14 '22 00:03 marbemac

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.

sastan avatar Mar 16 '22 10:03 sastan

Thank you! Ping me if ya need any extra testing or anything.

marbemac avatar Mar 16 '22 17:03 marbemac

Hey @marbemac, sorry it took me so long. Just to recap:

  1. you write "normal" tailwind classes
  2. these are passed to tw and your hash method adds a prefix
  3. 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.

sastan avatar May 09 '22 17:05 sastan

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.

marbemac avatar May 09 '22 21:05 marbemac

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.

stale[bot] avatar Mar 06 '23 02:03 stale[bot]

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.

stale[bot] avatar Jan 01 '24 20:01 stale[bot]