-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LATE_SETUP_CALL error with Next.js #12
Comments
For me, when using Webpack 5, the style is not pre-rendered on the server (which is what the setup for). |
Sorry for not responding earlier. I try to look into this at the end of the week. |
Unsure if this is the right issue to share this on. I also have this happen to values of a custom theme I've made, but only on a build and thus in production, not in development. It results in breaking classes that have mentions to these custom theme values, and thus breaking other styles as well. This happens at random during refresh, and most often during the first load of the site for any given client, in desktop, mobile, pagespeedinsights, etc. package.json"dependencies": {
"@twind/next": "^1.0.7",
"@twind/react": "^0.0.4",
"next": "^10.2.0",
"twind": "^0.16.16",
}, Themeconst config: Configuration = {
preflight: (preflight, { theme }) => ({
...preflight,
html: {
"scroll-behavior": "smooth",
"scroll-padding": "4.5rem",
},
"h1, h2, h3, h4, h5, h6": {
fontFamily: "Montserrat",
},
body: {
fontFamily: "Gotham",
},
// Modal background
".snipcart-modal__container, .snipcart-modal, .snipcart-cart-header": {
backgroundColor: `${theme("colors.gray.100")} !important`,
},
[etc...]
prefix: true,
theme: {
extend: {
fontFamily: { sans: ["Montserrat"], secondary: ["Gotham"] },
colors: {
...colors,
transparent: "transparent",
current: "currentColor",
gray: {
"50": "#f7f9f8",
"70": "#eff5f7",
"100": "#ebf1f4",
"200": "#d2dfe8",
"300": "#a7becb",
"400": "#7397a6",
"500": "#587684",
"600": "#475b66",
"700": "#37444d",
"800": "#262e36",
"900": "#171c23",
},
red: colors.red,
blue: colors.lightBlue,
yellow: colors.amber,
primary: {
logo: "#446C52",
saturated: "#67A147",
dark: "#35542F",
light: "#EDF2B0",
},
yellowLight: "#F4E9BD",
blueLight: "#D3E6E9",
lightBlueGrey: "#e9f1f2",
bg: "#EDF7EA",
newGreen: {
"50": "#F5F7F2",
"100": "#E8F0D9",
"200": "#CAE5B0",
"300": "#97C877",
"400": "#72B162",
"500": "#378B29",
"600": "#2D731B",
"700": "#275817",
"800": "#1C3C13",
"900": "#132411",
},
[more custom colors...]
},
container: {
padding: {
DEFAULT: "1rem",
sm: "2rem",
lg: "4rem",
xl: "5rem",
"2xl": "6rem",
},
},
boxShadow: (theme) => ({
highlighted: `0px 0px 2px 3px ${theme("colors.chocolate.200")}`,
}),
screens: { standalone: { raw: "(display-mode:standalone)" } },
};
}, _documentimport { FB_PIXEL_ID } from "@lib/fpixel";
import withTwindDocument from "@twind/next/shim/document";
import Document, { Head, Html, Main, NextScript } from "next/document";
import twindConfig from "../twind.config";
class CustomDocument extends Document {
render() {
return (
<Html lang="pt">
<Head>
<link rel="preconnect" href="https://app.snipcart.com" />
<link rel="preconnect" href="https://cdn.snipcart.com" />
<link href="/static/fonts/style.css" rel="stylesheet" />
<link href="/static/style.css" rel="stylesheet" />
</Head>
<body>
<Main />
<NextScript />
<style
dangerouslySetInnerHTML={{
__html: ` </style>
<link
rel="preload"
as="style"
onload="this.onload=null;this.rel='stylesheet'"
href="https://cdn.snipcart.com/themes/v3.0.31/default/snipcart.css"
crossOrigin="anonymous"
/>
<style>`,
}}
></style>
<script
crossOrigin="anonymous"
async
src="https://cdn.snipcart.com/themes/v3.0.31/default/snipcart.js"
></script>
<script src="/static/snipcart.js"></script>
<div
hidden
data-config-add-product-behavior="none"
id="snipcart"
data-api-key={process.env.SNIPCART_PUBLIC}
data-config-modal-style="side"
data-templates-url="/static/snipcart-templates.html"
></div>
</body>
</Html>
);
}
}
export default withTwindDocument(twindConfig, CustomDocument); _appimport FBPixelProvider from "@components/FacebookPixel";
import Layout from "@components/layout";
import { useNif, useSnipcart } from "@lib/snipcart";
import { wrapper } from "@redux/store";
import withTwindApp from "@twind/next/shim/app";
import { DefaultSeo } from "next-seo";
import { AppProps } from "next/app";
import Head from "next/head";
import * as React from "react";
import { useEffect } from "react";
import SEO from "../next-seo.config";
import twindConfig from "../twind.config";
function MyApp({ Component, pageProps }: AppProps) {
return (
<FBPixelProvider>
<Layout>
<>
<Head>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link rel="manifest" href="/site.webmanifest" />
<link
rel="mask-icon"
href="/safari-pinned-tab.svg"
color="#5bbad5"
/>
<meta name="theme-color" content="#ffffff" />
</Head>
<DefaultSeo {...SEO} />
<Component {...pageProps} />
</>
</Layout>
</FBPixelProvider>
);
}
export default wrapper.withRedux(withTwindApp(twindConfig, MyApp)); next.config.jsconst withPlugins = require("next-compose-plugins");
const withImages = require("next-images");
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
const { withSentryConfig } = require("@sentry/nextjs");
const config = {
future: {
webpack5: true,
},
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"],
});
return config;
},
};
module.exports = withPlugins([[withBundleAnalyzer, withImages]], config); |
I've been running into this too with WMR, so doesn't look to be tied to Next. (might be premature assumption, but does look to be tied to the lack of styles being prerendered) Repo + instructions to reproduce: https://github.com/rschristian/twind-late-setup-call-bug |
Has anyone solved this problem? Please let me know, thx a lot. |
As we run into some trouble with this and re-configuring twind during runtime I'm thinking about to allow |
Is there a way to check if setup function has already run from the user point of view? :) for me it happens because of HMR and I store the flag on if (!window.Twind) {
setup({});
window.Twind = true;
} |
Here's a more involved workaround: const createTwind = () => {
setup({
theme: {
extend: {
colors: {
"brand-red-500": "#FA3541",
},
},
},
});
// in my code here I create some custom sheets
return 123;
};
let singletonHolder: ReturnType<typeof createTwind> | undefined;
// call this function instead of `setup` itself
export function getTwind() {
return singletonHolder || (singletonHolder = createTwind());
}
// my typescript is a bit misconfigured, you might not need this
declare global {
interface NodeModule {
hot?: {
data: { singletonHolder?: typeof singletonHolder };
dispose: (callback: (data: { singletonHolder?: typeof singletonHolder }) => void) => void;
};
}
}
if (module.hot) {
// here I'm restoring my sheets, you can just check if twind is already initialized
singletonHolder = module.hot?.data?.singletonHolder || singletonHolder;
module.hot.dispose(data => {
// I'm storing my stuff, you will just mark that initialization happened
data.singletonHolder = singletonHolder;
});
} |
Hi there! Great work with Twind... it's an amazing concept and I am really loving the API.
I tried integrating it with Next.js + Webpack 5 and got this error:
A lot of times it's not really causing any issues (pages continue to work) but sometimes they cause
Internal Server Error
to show up for some pages.package.json
twind.config.js
pages/_document.js
pages/_app.js
next.config.js
The text was updated successfully, but these errors were encountered: