stitchesjs / stitches

[Not Actively Maintained] CSS-in-JS with near-zero runtime, SSR, multi-variant support, and a best-in-class developer experience.

Home Page:https://stitches.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for Next.js 13

hmbrg opened this issue · comments

Since Next.js 13 was released yesterday, the beta docs list Stitches as not being support as of right now.

There is however a guide on how to integrate styled-jsx that look very similar to how Stitches could be integrated: https://beta.nextjs.org/docs/styling/css-in-js

Are there any plans to officially offer support for Next.js 13?

I barely tested this, but seems to be working. Again, I tested this for like 2 mins, so take that into consideration. Based on the example:

"use client"

import React from "react"
import { useServerInsertedHTML } from "next/navigation"
import { getCssText } from "../../stitches.config"

export function ServerStylesheet({ children }) {
  useServerInsertedHTML(() => {
    return <style id="stitches" dangerouslySetInnerHTML={{ __html: getCssText() }} />
  })

  return children
}

and on the layout:

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </head>
      <body>
        <ServerStylesheet>{children}</ServerStylesheet>
      </body>
    </html>
  )
}

@jpmaga css utility method breaks the app (both on client and server). And stitches should update the docs for next 13 app dir. Because its a totally different way of doing things than the pages directory

It seems to only work with client-side rendering, is it right?

Is there any way for making the app awaits for css before loads?

@rodrigodh you need to force the prop into a string, then it works, this is actually a bug on react dom server, need to post an issue about this there.

I noticed that sometimes the style dont load at all too.

@rodrigodh you need to force the prop into a string, then it works, this is actually a bug on react dom server, need to post an issue about this there.

I noticed that sometimes the style dont load at all too.

'use client';

import { useServerInsertedHTML } from 'next/navigation';
import { getCssText } from './stitches.config';

export function ServerStylesheet({
  children,
}: {
  children: JSX.Element;
}): JSX.Element {
  useServerInsertedHTML(() => {
    return (
      <style
        id="stitches"
        dangerouslySetInnerHTML={{ __html: String(getCssText()) }}
      />
    );
  });

  return children;
}

Tried this but did not work, is it another prop?

@rodrigodh getCssText() returns a string @darklight9811 could you elaborate?

@rodrigodh @vitharanagedonjani-i2e, sorry for the delay, but I meant the css utility, not the getCssText(), another part of the issue.

const buttonProps = css({})

function Button (props) {
  return <button className={buttonProps(props)}>{props.children}</button>
}

Does this fix the issue where styles are not loading in server side? @darklight9811

Does this fix the issue where styles are not loading in server side? @darklight9811

Absolutely not

This link shows how it worked for me, but only on the client side.
https://stackblitz.com/edit/nextjs-ftij4p?file=app/ServerStylesSheet.tsx

But all pages and components you need to use with stitches, you put this flag on top the code 'use client'. This specify the component or page is run on client side.

I‘d love to see support for this too.

I don't 100% understand the issue but I suspect getCssText is too magical and something like a StyleSheet API needs to be exposed.

I am also on the need for a migration for Nextjs 13 and i would the support for this as well!

This works for me, inside of the Layout.tsx file generated in the app directory folder, but i dont sure.

import {getCssText, globalStyles} from '@/ui'
import './globals.css'

export default function RootLayout({children}: {children: React.ReactNode}) {
  globalStyles()
  return (
    <html lang="en">
      <head>
        <style id="stitches" dangerouslySetInnerHTML={{__html: getCssText()}} />
      </head>
      <body>{children}</body>
    </html>
  )
}

@DavidRojas1612 That's great! Seems extremely simple, thanks for commenting to let us know.
Have you noticed any gaps or issues since last week?

commented

@DavidRojas1612 @timweightman The above seems to work albeit I am seeing a few errors:
Screenshot 2023-01-27 at 1 19 08 pm

This works for me, inside of the Layout.tsx file generated in the app directory folder, but i dont sure.

@DavidRojas1612 Does this work for you with fast refresh ? It does work on my side but if I do a change, the app refresh without stitches style and I have to manually refresh to get the style back.

@DavidRojas1612 @timweightman The above seems to work albeit I am seeing a few errors: Screenshot 2023-01-27 at 1 19 08 pm

I am not certain why you're getting this error - the content of your RootLayout component should match @DavidRojas1612 example exactly. Is there anything you've done differently, maybe show us some code?

@DavidRojas1612 Does this work for you with fast refresh ? It does work on my side but if I do a change, the app refresh without stitches style and I have to manually refresh to get the style back.

I'm in the same boat - must manually refresh to get styles back. I believe the CSS generated and put into the <style id="stitches" element is being mangled. When I modify CSS for a Stitches styled component and compare the content of that style element, the whole block of styles for all components has been removed, only the global styles remain.

I wonder if it's related to NextJS Fast Refresh...?

@timweightman I think getCSsText is broken in general on the client #1094

I too am only seeing the global styles in the output

Ooo I just did a setTimeout to use getCssText and it has all the styles now. I'm thinking that if you call it too soon it doesn't work

Ooo I just did a setTimeout to use getCssText and it has all the styles now. I'm thinking that if you call it too soon it doesn't work

@hipstersmoothie What does your code looks like? I'd like to have it as a reference.

I solved this problem creating a isolated component, and applying the getCssText there for example:

MyComponent:

import { getCssText } from '@/styles/stitches.config'

export const StyleSheet = () => {
  return (
		<style id="stitches" dangerouslySetInnerHTML={{ __html: getCssText() }} />
	)
}

layout.tsx

import { StyleSheet } from '@/components/StyleSheet'
import { GlobalCss } from '@/styles/global'

export default function RootLayout({
	children,
}: {
	children: React.ReactNode
}) {
	return (
		<html lang="en" className={inter.className}>
			<head>
				<StyleSheet />
			</head>
			<body>
				{children}
				{GlobalCss()}
			</body>
		</html>
	)
}

This way work because that in nextjs 13 all component are SSR (Server Side Rendering), then this stitche style is load on SSR and the screen already work with this style!

I hope that help everyone! Thank you guys!

I solved this problem creating a isolated component, and applying the getCssText there for example:

MyComponent:

import { getCssText } from '@/styles/stitches.config'

export const StyleSheet = () => {
  return (
		<style id="stitches" dangerouslySetInnerHTML={{ __html: getCssText() }} />
	)
}

layout.tsx

import { StyleSheet } from '@/components/StyleSheet'
import { GlobalCss } from '@/styles/global'

export default function RootLayout({
	children,
}: {
	children: React.ReactNode
}) {
	return (
		<html lang="en" className={inter.className}>
			<head>
				<StyleSheet />
			</head>
			<body>
				{children}
				{GlobalCss()}
			</body>
		</html>
	)
}

This way work because that in nextjs 13 all component are SSR (Server Side Rendering), then this stitche style is load on SSR and the screen already work with this style!

I hope that help everyone! Thank you guys!

For me, this solution works well, but fast refresh does not immediately work (the styles are not applied), requiring a manual refresh.

I solved this problem creating a isolated component, and applying the getCssText there for example:

MyComponent:

import { getCssText } from '@/styles/stitches.config'

export const StyleSheet = () => {
  return (
		<style id="stitches" dangerouslySetInnerHTML={{ __html: getCssText() }} />
	)
}

layout.tsx

import { StyleSheet } from '@/components/StyleSheet'
import { GlobalCss } from '@/styles/global'

export default function RootLayout({
	children,
}: {
	children: React.ReactNode
}) {
	return (
		<html lang="en" className={inter.className}>
			<head>
				<StyleSheet />
			</head>
			<body>
				{children}
				{GlobalCss()}
			</body>
		</html>
	)
}

This way work because that in nextjs 13 all component are SSR (Server Side Rendering), then this stitche style is load on SSR and the screen already work with this style!

I hope that help everyone! Thank you guys!

This worked for me only when it's an isolated component with no other functionality (ie, global styles in a separate file)

commented

The above solutions seem to be working for me too with:
stylesheets.tsx

export default function StyleSheet() {
	return (
		<style id="stitches" dangerouslySetInnerHTML={{ __html: getCssText() }} />
	);
}

globalCSS.tsx

export default function GlobalCSS() {
	return globalStyles();
}

and

layouts.tsx

export default function RootLayout({ children }: Props) {
	return (
		<html lang="en" className={Graphik.className}>
			<head>
				<StyledSheet />
			</head>
			<body>
				<Providers>{children}</Providers>
				<Analytics />
				{GlobalCSS()}
			</body>
		</html>
	);
}

@jbowa I'm wondering why {GlobalCSS()} goes as last body children and not the first?

commented

@IvanKuzyshyn Either way I am still having issues. As much as I hate it, I think the smart move here would be to move to TailwindCSS.

I've followed the steps to set up Stitches with Next.js 13, but I'm having issues with rehydration. Sometimes it works, sometimes it doesn't, and I have to do a manual refresh. Additionally, the styles are not being applied consistently and sometimes load without any styling before eventually applying the correct styles. Is there anything I can do to improve this? Any other tips or suggestions?

I've followed the steps to set up Stitches with Next.js 13, but I'm having issues with rehydration. Sometimes it works, sometimes it doesn't, and I have to do a manual refresh. Additionally, the styles are not being applied consistently and sometimes load without any styling before eventually applying the correct styles. Is there anything I can do to improve this? Any other tips or suggestions?

Having this issue as well. Had to revert to using the pages folder to avoid these issues.

Hi guys!

Based on these examples: https://beta.nextjs.org/docs/styling/css-in-js, this works for me:

app/registry.tsx

"use client";

import React, { useState } from "react";
import { useServerInsertedHTML } from "next/navigation";
import { getCssText } from "@/styles/styles.config";

export default function StitchesRegistry({ children }: { children: React.ReactNode }) {
  const [isRendered, setIsRendered] = useState(false);

  useServerInsertedHTML(() => {
    if (!isRendered) {
      setIsRendered(true);
      return <style id="stitches" dangerouslySetInnerHTML={{ __html: getCssText() }} />;
    }
  });

  return <>{children}</>;
}

app/layout.tsx

import { Providers } from "./providers";
import StitchesRegistry from "./registry";

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <head />
      <body>
        <StitchesRegistry>
          <Providers>{children}</Providers>
        </StitchesRegistry>
      </body>
    </html>
  );
}

Hope to help someone! Cheers!

@ricardolandolt that registry does seem to make fast refresh work just fine in my (very limited) testing!

commented

It should still be noted that only client components will get any styling by using the 'stitches registry' solution.

Server components do not get styling output. They will get a CSS class applied, but it won't be flushed within the generated style element content.

@ricardolandolt do server components get styling in your use-case?