Ionic-framework: bug: @ionic/react doesn't work [great] with Next.js

Created on 22 Nov 2019  路  7Comments  路  Source: ionic-team/ionic-framework

Bug Report

Versions:

  • @ionic/react : 4.11.5
  • next : 9.1.4

Current behavior:

Out-of-the-box error :

./node_modules/ionicons/dist/ionicons/svg/ios-switch.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><circle cx="144" cy="368" r="42"/><path d="M367.5 272h-223C91.2 272 48 315.2 48 368.5S91.2 464 144.5 464h223c53.3 0 96.5-42.2 96.5-95.5S420.8 272 367.5 272zM144 432c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z"/><circle cx="368" cy="144" r="42"/><path d="M144.5 240h223c53.3 0 96.5-42.2 96.5-95.5S420.8 48 367.5 48h-223C91.2 48 48 91.2 48 144.5S91.2 240 144.5 240zM368 80c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64z"/></svg>

After adding an SVG loader (next-optimized-images) :

ReferenceError: window is not defined
    at Object.<anonymous> (/home/***/front-next/node_modules/ionicons/dist/cjs/chunk-01d5c78f.js:24:13)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/***/front-next/node_modules/ionicons/dist/cjs/index.cjs.js:5:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)

Updating webpack's config with config.output.globalObject = 'this' doesn't change anything (if I get it well that's because the file that is causing the problem was created by yarn at yarn add @ionic/react time and not at my app's build time) :

ReferenceError: window is not defined
    # still same file
    at Object.<anonymous> (/home/***/front-next/node_modules/ionicons/dist/cjs/chunk-01d5c78f.js:24:13)
    ...

Expected behavior:

I expected to be able to import Ionic's React components in a Next.js app without build errors :

import {IonHeader} from '@ionic/react';

export default () => (
  <IonHeader>
  </IonHeader>
);

Steps to reproduce:

  • Create a Next.js app (with TypeScript in my case)
  • Add @ionic/react as a dependency
  • Import a Ionic React component like IonHeader and use it

Ionic info:
Not using Ionic CLI.

Workaround:

Works when dynamically importing the component but not very handy, no SSR and no tree-shaking (I guess? cause the page's size went from 2.4MB to 4.4MB) :

// import {IonHeader} from '@ionic/react';
import dynamic from 'next/dynamic';

const IonHeader = dynamic(
  async () => {
    const mod = await import('@ionic/react');
    return mod.IonHeader;
  },
  { ssr: false } // this is what makes it work
);

export default () => (
  <IonHeader>
  </IonHeader>
);
react

Most helpful comment

Ionic React support for NextJS is in active development. Expect to hear more on it soon.

All 7 comments

In the latest version of Ionicons, the svgs are not exported as dataurls, which avoid requiring the tooling that needs to be able to load .svg extensions, and copying static svg files to webpack's build directory.

Any updates on this Ionic + Next.js integration, please?

Bumping this thread. we would like to know the update for this.

Ionic React support for NextJS is in active development. Expect to hear more on it soon.

For those wanting to hack around in the meantime, this should save you some time. Note, I'm not connected to the ionic project, and it's unclear what steps might be required to switch to the upcoming official NextJS support... but probably your page outlines will remain the same.

lib/ionic.js: (Implements above workaround for any property / component)

import dynamic from 'next/dynamic';

// https://github.com/ionic-team/ionic/issues/19975
module.exports = new Proxy({}, {
  get: function(obj, prop) {
    return prop === '__esModule' ? true : dynamic(
      async () => (await import('@ionic/react'))[prop],
      { ssr: false }
    );
  }
});

pages/example.js: (how to use)

// import from '../lib/ionic' instead of '@ionic/react`
import { IonPage, IonHeader, etc } from '../lib/ionic';

pages/_app.js: (other general setup)

/* Core CSS required for Ionic components to work properly */
import '@ionic/react/css/core.css';

/* Basic CSS for apps built with Ionic */
import '@ionic/react/css/normalize.css';
import '@ionic/react/css/structure.css';
import '@ionic/react/css/typography.css';

/* Optional CSS utils that can be commented out */
import '@ionic/react/css/padding.css';
import '@ionic/react/css/float-elements.css';
import '@ionic/react/css/text-alignment.css';
import '@ionic/react/css/text-transformation.css';
import '@ionic/react/css/flex-utils.css';
import '@ionic/react/css/display.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

How are you guys getting this to work? Iv'e seen lots of small snippets suggesting people are currently using ionic with next however (and i'm no expert in ionic) iv'e read the docs and blocked by literally the first step how did you get around this?

I can run npm run build and set ionic webDir to ./.next/serverless/pages/ however it will reference assets that are in ./next/static/**/* which wont be included in the folder the server is running on therefore will 404 so your page will load without css/assets/etc

That's ontop of obviously not being able to even use getInitialProps in pages/index.js because then it wont output a index.html which webDir needs.

Any suggestions for me? even a full guide to limitations of next/ionic and where they are compatible and where they aren't?

Was this page helpful?
0 / 5 - 0 ratings