IonicReact

Using Ionic Framework into Next.js application (without using @ionic/react)

For now, we can not use @ionic/react into Next.js application. When we install and import it, we’ll get […]

広告ここから
広告ここまで

For now, we can not use @ionic/react into Next.js application. When we install and import it, we’ll get these error.

% yarn build 
yarn run v1.22.5
$ yarn --cwd packages/web-app build
$ next build
info  - Creating an optimized production build  
info  - Compiled successfully

> Build error occurred
ReferenceError: HTMLElement is not defined

Why can not use it?

Probably, the answer is a Web Component.
Ionic components are Web Component (made by Stencil), and Web Component should register it manually.
Stencil provides a defineCustomElements() method, and Ionic React calls it internally.

But, in SSR, several DOM properties are missing in NodeJS env.
So the function will be failed, and several properties will be “not defined”.

Solution: using @ionic/core instead of @ionic/react

In the Next.js examples, they show us the example application using Stencil.
https://github.com/vercel/next.js/tree/canary/examples/with-stencil

It means we can use a Web Component created by Stencil can use in the Next.js application.
And Ionic components are made by Stencil.

So, If we want to use “Ionic Component”, we can use it as a Web Component.

Step by step

Step1: Create Next.js application

# Setup project
$ npx create-next-app nextjs-ionic

# Go to web root
$ cd nextjs-ionic

# Put tsconfig.json
$ touch tsconfig.json

# Install TypeScript packages
$ yarn add -D typescript @types/react @types/node

Step2: Install Ionic components

Ionic components are divided into the two library. If you want to use IonIcon or ion-icon, we should install both.

$ yarn add @ionic/core ionicons

Step3: Define Custom Elements Types

We use Ionic component as a JSX element, so we need to declare these element types.

pages/_app.tsx

import { JSX as LocalJSX} from '@ionic/core'
import {JSX as IoniconsJSX} from 'ionicons'
import { HTMLAttributes, ReactText } from 'react'

type ToReact<T> = {
  [P in keyof T]?: T[P] & Omit<HTMLAttributes<Element>, 'className'> & {
    class?: string;
    key?: ReactText;
  }
}

declare global {
  export namespace JSX {
    interface IntrinsicElements extends ToReact<LocalJSX.IntrinsicElements & IoniconsJSX.IntrinsicElements> {}
  }
}

Step4: Define Custom Element and import CSS

When we want to use Ionic component, we should define these component.

pages/_app.tsx

import React, { useEffect } from 'react'
import { defineCustomElements as ionDefineCustomElements } from '@ionic/core/loader';
/* Core CSS required for Ionic components to work properly */
import '@ionic/core/css/core.css';

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

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

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    ionDefineCustomElements(window)
  })
  return <p>Hello</p>
}

export default MyApp

Finally: Use Ionic component into the application

Finally, we can use Ionic component!

Once declare these type, we don’t have to declare again each component files.

pages/home.tsx

import Image from 'next/image'

export default function Home() {
  return (
        <ion-refresher slot="fixed" closeDuration="10ms">
          <ion-refresher-content />
          <ion-card>
            <ion-card-header>
              <ion-card-subtitle>Card Subtitle</ion-card-subtitle>
              <ion-card-title>Card Title</ion-card-title>
            </ion-card-header>

            <ion-card-content>
            <Image
              src="./images"
              alt="Picture of the author"
              width={500}
              height={300}
            />
              Keep close to Nature's heart... and break clear away, once in awhile,
              and climb a mountain or spend a week in the woods. Wash your spirit clean.
            </ion-card-content>
          </ion-card>
        </ion-refresher>
  )
}

Example application

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts