telekom / scale

Scale is the digital design system for Telekom products and experiences.
https://telekom.github.io/scale/
Other
376 stars 83 forks source link

NextJS with 'use client', StaticSiteGeneration and output: export #2250

Open SebastianGode opened 10 months ago

SebastianGode commented 10 months ago

Scale Version ^3.0.0-beta.139

Framework and version ^14.0.5-canary.43

Code Reproduction This will error out due to this issue: https://github.com/vercel/next.js/issues/54393

'use client';

import Footer from '/components/Footer';
import Header from '/components/Header';
import '/styles/general.css'
import { defineCustomElements, applyPolyfills } from '@telekom/scale-components/loader';
import '@telekom/scale-components/dist/scale-components/scale-components.css';
import { useLayoutEffect } from 'react'
import { i18n } from '/lib/i18n_config'

export default function RootLayout({ children, params }) {
// This whole hook is needed for Scale, I can't remove it
  useLayoutEffect(() => {
    applyPolyfills().then(() => {
      defineCustomElements(window)
    })
  }, [])
  return (
    <html lang={params.lang}>
      <head>
        <link rel="icon" href="/favicon.ico" sizes="any" />
      </head>
      <body>
        <Header></Header>
        {children}
        <Footer></Footer>
      </body>
    </html>
  )
}

// Function to generate static pages
export async function generateStaticParams() {
  return i18n.locales.map((locale) => ({ lang: locale }))
}

The code also can be found in the i18n branch here: https://github.com/opentelekomcloud-infra/circle-partner-navigator-frontend/blob/i18n/app/%5Blang%5D/layout.js Is there any way to prerender Scale without doing this on the Client-Side using React's useLayoutEffect Hook? This would also be faster as the client doesn't need to fetch the complete JS files form Scale first and just after that start rendering.

felix-ico commented 10 months ago

Hi @SebastianGode, we had a similar issue https://github.com/telekom/scale/issues/1773 a while back and I found this nextjs/stencil example there https://github.com/vercel/next.js/blob/canary/examples/with-stencil/packages/web-app/pages/_app.js .. It seems like they also suggest using useLayouEffect although, as you say, there may be better performing solutions.

I found this https://css-tricks.com/using-web-components-with-next-or-any-ssr-framework/#aa-custom-bundling-web-component-code, and quickly tested it by replacing the contents of their shoelace-bundle.js file with our defineCustomElements - it seems to work, do you think this would be appropriate for your use case?

amir-ba commented 3 weeks ago

@SebastianGode were you able to test what Felix-ico suggested?

SebastianGode commented 3 weeks ago

@amir-ba Yes, but sadly this is still rendering the actual CSS theme on the client-side. I found no way to prerender it.