ionic-framework: bug: Ionic component styles do not apply in Next.js application

Prerequisites

Ionic Framework Version

  • v4.x
  • v5.x
  • v6.x

Current Behavior

SSR/SSG of Nextjs do not work with ionic/react: “^6.0.0”. The version worked well with ionic/react 5. I have reached out to ionic community in discord and was suggested creating the issue. The styles do not apply the behaviour is odd when we use SSR or SSG. It works well on client side though.

Expected Behavior

I expect the code to work similar as it worked on version 5.9.3. All the styles do apply there.

Steps to Reproduce

  1. git clone https://github.com/MarianDabrowski/next-app
  2. cd next-app
  3. npm i
  4. npm run dev

Code Reproduction URL

https://github.com/MarianDabrowski/next-app

Ionic Info

[WARN] You are not in an Ionic project directory. Project context may be missing.

Ionic:

Ionic CLI : 6.19.0

Utility:

cordova-res : 0.15.4 native-run : not installed globally

System:

NodeJS : v17.3.1 npm : 8.5.3 OS : macOS Monterey

Additional Information

Based on the discussion with @sean-perkins I believe Sean is right saying: “…custom elements should workin SSR/SSG, so the fact that it isn’t, is a little concerning. The root issue is likely Stencil, if the styles are not being applied, but I would recommend creating a ticket in ionic-framework, since the UI kit should support Next.js.”

_app.tsx is rendered before each page render As i understand setupIonicReact shall be called at the initial stage.

Altering pages/index.tsx to

const Home: NextPage = () => {
  const [component, setComponent] = useState(<div>I Am a placeholder</div>);

  useEffect(() => {
    setTimeout(() => {
      setComponent(<App />);
    }, 3000);
  });
  return component;
};

makes the code work properly

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 4
  • Comments: 27 (11 by maintainers)

Most upvoted comments

Context from my discovery & our discord conversation:

The web components are being defined/registered/detected correctly when served through Next.js. The style tag for each web component is not being rendered though. There is an inline comment where the style blocks should be. This results in all the components being in a broken/styleless state.

The fact that it worked < v6, suggests it is an issue with the custom elements build.

I’ve confirmed that nothing in the Next.js project configuration points at an issue with the reproduction app, so my thoughts are that:

  1. Next.js is somehow stripping out those styles
  2. Stencil is unable to apply the styles in the right execution context with Next.js.

The main issue is that when setting up the config we return early if no window is available: https://github.com/ionic-team/ionic-framework/blob/main/core/src/global/ionic-global.ts#L18

This means that the in-memory config object is never created. As a result, certain things like the default mode are not defined. The in-memory config should be usable even if window is not defined, so we likely need to re-arrange the initialize function to not return early. Instead, we likely need to wrap the window-specific parts in if/else blocks so that the in-memory config is still created even in SSR/SSG environments.