next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Icomoon font will not be rendered with emotion enabled

Open dominikmatt opened this issue 3 years ago • 6 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: x64
  Version: Darwin Kernel Version 21.6.0: Sat Jun 18 17:07:25 PDT 2022; root:xnu-8020.140.41~1/RELEASE_X86_64
Binaries:
  Node: 14.15.0
  npm: 7.11.1
  Yarn: 1.22.18
  pnpm: N/A
Relevant packages:
  next: 12.3.1-canary.0
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Describe the Bug

Background Since we switched to nextjs@12 we only got minified css classes on development for our @emotion styles.

The Problem Now we tried to enable emotion with the compiler.emotion = true configuration. With that emotion works well except our icomoon font. The icomoon font will be loaded and added to the styles... but not rendered. I'm not sure what the problem is exactly, for me all the things looks well.

Expected Behavior

Icons should be rendered as a font

Link to reproduction

https://github.com/dominikmatt/nextjs-emotion

To Reproduce

  • Add emotion to your nextjs project
  • Add a emotion component and define all the icons inside of it
  • Enable emotion on next-configuration
const nextConfig = {
  compiler: {
    emotion: true, // Change to false to get the icon rendered
  },
}

dominikmatt avatar Sep 09 '22 07:09 dominikmatt

Taking a look at this.

rubytree33 avatar Sep 09 '22 16:09 rubytree33

It breaks because if compiler.emotion = true, the inline stylesheet in index.js is emitted with content: "\\e904" rather than content: "\e904". This is what it looks like in the original source in index.js. And no other escaping works in this template string.

So my guess is this is introduced at compile time by next-swc/crates/emotion, specifically here which is called to modify the template string after styles.tagname. I think a layer of string escaping is introduced here implicitly in type conversion, so I'm trying an explicit conversion.

rubytree33 avatar Sep 09 '22 21:09 rubytree33

Looking into it a little more, it seems that all those conversions in swc don't escape anything.

But after some investigation and looking at related issues (emotion-js/emotion#1755, emotion-js/emotion#2802) I found #38301 which is apparently the root of the problem.

Tagged template strings basically have two forms: the "cooked" one which translates escape sequences, and the "raw" one which leaves the string exactly as it appears in the source. (See here for more info.) So I think this is the line responsible: https://github.com/vercel/next.js/blob/8bc587aa30099bdf3ee379fe0b1a2fe3387801cf/packages/next-swc/crates/emotion/src/lib.rs#L340

q.raw here selects the raw form, and it seems the transformations which come later (in this function) never attempt to "cook" the string.

@kdy1 Are you still working on #38301? If not I'll try making a pr that should resolve both.

rubytree33 avatar Sep 09 '22 22:09 rubytree33

No I'm not working on it

kdy1 avatar Sep 10 '22 03:09 kdy1

@rubytree33 When can we expect a fix here? Looks like it is already fixed but not merged…

dominikmatt avatar Oct 13 '22 12:10 dominikmatt

That's up to the maintainers, since I can't merge the PR myself.

rubytree33 avatar Oct 13 '22 19:10 rubytree33

https://github.com/swc-project/plugins/pull/260 should fix this issue

kdy1 avatar Jan 31 '24 03:01 kdy1

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Feb 14 '24 12:02 github-actions[bot]