ben-rogerson / twin.macro

🦹‍♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js (emotion, styled-components, solid-styled-components, stitches and goober) at build time.
MIT License
7.89k stars 184 forks source link

styled-components: Error in Next.js 13 when using the app directory #780

Closed adiba closed 1 year ago

adiba commented 1 year ago

I applied this installation guide (Twin + Next.js + Styled Components + TypeScript) to my Next.js app that uses the new app directory structure.

I got this error when navigating to my page:

error - node_modules\styled-components\dist\styled-components.cjs
.js (1:13064) @ createContext
error - createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.o
rg/docs/messages/context-in-server-component
    at eval (webpack-internal:///(sc_server)/./node_modules/styled-components/dist/styled-components.cjs.js:351:12)
    at Object.(sc_server)/./node_modules/styled-components/dist/styled-components.cjs.js (C:\Users\...\next-twin-test\.next\server\app\page
.js:899:1)
    at __webpack_require__ (C:\Users\...\next-twin-test\.next\server\webpack-runtime.js:33:42)
    at eval (webpack-internal:///(sc_server)/./components/InputThing.tsx:6:75)
    at Object.(sc_server)/./components/InputThing.tsx (C:\Users\...\next-twin-test\.next\server\app\page.js:701:1)
    at __webpack_require__ (C:\Users\...\next-twin-test\.next\server\webpack-runtime.js:33:42)
    at eval (webpack-internal:///(sc_server)/./app/page.tsx:6:80)    at Object.(sc_server)/./app/page.tsx (C:\Users\...\next-twin-test\.nex
t\server\app\page.js:679:1)
    at Function.__webpack_require__ (C:\Users\...\next-twin-test\.next\server\webpack-runtime.js:33:42)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  type: 'TypeError',
  page: '/'
}

After removing all code form the GlobalStyles as BaseStyles import, the error is gone.

I added 'use client'; to the top of GlobalStyles.tsx, to no effect.

I know the installation for the app directory is not documented yet, thus likely not officially supported. Thanks a lot in advance for any assistance nonetheless! 😊

ben-rogerson commented 1 year ago

If it's having issues with twins magic GlobalStyles import, perhaps you can try using the simple css object version (globalStyles).

Something like this:

// styles/GlobalStyles.tsx
import React from 'react'
import { createGlobalStyle, CSSObject } from 'styled-components'
import tw, { theme, globalStyles } from 'twin.macro'

const GlobalStyles = createGlobalStyle({
  body: {
    WebkitTapHighlightColor: theme`colors.purple.500`,
    ...tw`antialiased`,
  },
  ...(globalStyles as CSSObject),
})

export default GlobalStyles
adiba commented 1 year ago

Thanks a lot for you quick response! And sorry for the incomplete sentence up there 😆

The follwing throws the same error, so I believe the issue is with styled-components?

'use client';

import React from 'react'
import { createGlobalStyle } from 'styled-components'

const CustomStyles = createGlobalStyle({
    body: {},
})

export const GlobalStyles = () => <></>
ben-rogerson commented 1 year ago

That looks like the cause here - perhaps the answer is in the new beta docs here.

fredrivett commented 1 year ago

I'm following the link in the previous comment, adding a lib/registry.tsx page with the first few lines being:

"use client";

import React, { useState } from "react";

But I'm getting the following error:

wait  - compiling...
error - ./src/lib/registry.tsx
ReactServerComponentsError:

You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

   ,-[/[redacted]/src/lib/registry.tsx:1:1]
 1 | import { jsxDEV as _jsxDEV, Fragment as _Fragment } from "react/jsx-dev-runtime";
 2 | import React, { useState } from "react";
   :                 ^^^^^^^^
 3 | import { useServerInsertedHTML } from "next/navigation";
 4 | import { ServerStyleSheet, StyleSheetManager } from "styled-components";
 5 | export default function StyledComponentsRegistry({ children  }) {
   `----

Maybe one of these should be marked as a client entry with "use client":
  src/lib/registry.tsx
  src/app/layout.tsx

As you can see the "use client" line has been removed during the build process at some point so Next is throwing up, and I'm unsure what caused it's removal or how I can stop it being removed.

I'm using the withTwin setup as detailed here that was all working as expected before moving to Next 13's /app directory.

I've spent a couple hours digging into this but yet to find the solution, so posting here both in case someone knows, and also so I can follow up later with a solution if I find one.

EDIT: I've managed to create a small reproducible repo for this, so have created a separate issue for investigation.