twin.macro icon indicating copy to clipboard operation
twin.macro copied to clipboard

Next 14 layout shift (maybe css load after render)

Open minemos opened this issue 1 year ago • 3 comments

https://github.com/ben-rogerson/twin.macro/assets/24834933/bc12dae0-41e8-4501-addb-2476085b0169

copied from example project using app dir and next 14

package.json

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/css": "^11.11.2",
    "@emotion/react": "^11.11.1",
    "@emotion/server": "^11.11.0",
    "@emotion/styled": "^11.11.0",
    "cssnano": "^6.0.1",
    "next": "14.0.3",
    "react": "^18",
    "react-dom": "^18",
    "tailwind-scrollbar-hide": "^1.1.7"
  },
  "devDependencies": {
    "@babel/core": "^7.23.3",
    "@babel/plugin-syntax-typescript": "^7.23.3",
    "@babel/preset-react": "^7.23.3",
    "@babel/preset-typescript": "^7.23.3",
    "@emotion/babel-plugin": "^11.11.0",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10.4.16",
    "babel-loader": "^9.1.3",
    "babel-plugin-macros": "^3.1.0",
    "babel-plugin-styled-components": "^2.1.4",
    "eslint": "^8",
    "eslint-config-next": "14.0.3",
    "postcss": "^8.4.31",
    "styled-components": "^6.1.1",
    "tailwindcss": "^3.3.0",
    "twin.macro": "^3.4.0",
    "typescript": "^5"
  },
  "babelMacros": {
    "twin": {
      "preset": "emotion"
    }
  }
}

src/app/GlobalStyles.js

"use client";

import React from "react";
import { Global } from "@emotion/react";
import { css, GlobalStyles as BaseStyles } from "twin.macro";

const GlobalStyles = () => (
  <>
    <BaseStyles />
    <Global styles={css({})} />
  </>
);

export default GlobalStyles;

src/app/layout.tsx

import "./globals.css";
import GlobalStyles from "./GlobalStyles";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <GlobalStyles />
        {children}
      </body>
    </html>
  );
}

src/app/page.tsx

/** @jsxImportSource @emotion/react */
"use client";
import "twin.macro";

const App = () => (
  <div tw="flex flex-col items-center justify-center h-screen">
    <div tw="flex flex-col justify-center h-full gap-y-5">asdf</div>
  </div>
);

export default App;

It caused layout shift

seems like css is load after rendering

minemos avatar Nov 23 '23 05:11 minemos

This looks like an issue between Emotion and Next - Emotion probably needs to have a style cache set.

Check this thread for some examples on this.

ben-rogerson avatar Nov 23 '23 23:11 ben-rogerson

That can't be solution I think. (Also I tried)

I think problem is about server component and client component.

But that component (registry) also using client component.

To use full features in next js app dir, we need to use server component.

Anyway, point is server component is rendered at server but server have no css to render So client re render, and it cause layout shift

minemos avatar Nov 28 '23 09:11 minemos

@minemos - did you find any solution for the above issue?

isahuja2 avatar Aug 10 '24 03:08 isahuja2