šŸ–– Greetings, this site is prototype for low code CMS deployments: Discover MoreStar on GitHub

SKNOW.IT

Cover Image for Build a Headless WordPress React App with Ionic

Build a Headless WordPress React App with Ionic

DO IT WITH

WorDpress

React &

Ionic

Do you yearn to create high end custom mobile apps, dynamically populated using the WordPress API?

Combining the flexibility of a mature CMS like WordPress with the performance benefits of a JavaScript library like React and the mobile capabilities of Ionic can produce a glorious end product.

WordPress and React are two fabulous technologies, widely used in web development.

WordPress is an incredibly popular and immensely flexible content management system (CMS) that allows you to create and manage a website, even if you have no coding knowledge whatsoever. WordPress currently powers 43.1% of websites on the World Wide Web.

React, by far the most popular JavaScript library, it is used to build highly responsive user interfaces. It is declarative and component-based, meaning you can reuse components to create complex UIs in a short time.

Uniting these two technologies with Ionic, a framework for building cross-platform mobile apps, allows developers to create bespoke and feature-rich applications with minimal time investment to get a functional system.

In this tutorial, we’ll show you how to build a Headless WordPress app with React & Ionic.

Ionic is a free and open source component library for building apps that run on iOS, Android, Electron, and the Web.

How to create an Ionic React App leveraging the WordPress REST API as a Backend, an introduction.

With Ionic you can build for any platform from a single codebase using webs standard technologies: HTML, CSS, and JavaScript.

In this guide, we’ll walk through the process of building a WordPress-powered React app with Ionic. Follow along to learn the fundamentals of getting started with Ionic app development.

N.B. This demo uses the native WordPress REST API as the data source.

Don’t panic!
If you’re new to any of these technologies; we’ll keep things friendly and straightforward.

  • Prerequisites
  • Beginning Development
    • Step 1: Install Ionic
    • Step 2: Create a new Ionic React app
    • Step 3: Create the WordPress REST API client

Let’s Get Started

Prerequisites

Before diving into the development, make sure you have the following installed on your machine:

You can check these are installed by opening your terminal or command prompt and running these commands:

node --version
npm --version
git --version

Whilst not necessary, you may also want to familiarise yourself with:

šŸ¦¾ So, without further ado. Let’s build an App! šŸš€

Beginning Development

Step 1: Install Ionic

First we need to install the base libraries and frameworks, to do this:

  1. Open your terminal or command prompt
  2. Run the following command
npm install -g @ionic/cli

The Ionic command line interface (CLI) is the official tool for developingĀ IonicĀ apps, theĀ -gĀ option is used toĀ install packages globally.Ā You only need to run this on the initial dev environment setup, once done the global commandĀ ionicĀ can be used create further Ionic React projects.

Step 2: Create a new Ionic React app

We’ll need to create a new Ionic React application, the starting point can be bootstrapped from the Ionic templates.

In your local development directory.

Run the following command:

ionic start my-demo-app tabs --type=react

This will create a new Ionic React App named “my-demo-app” (you can change this to whatever name you prefer) from the default tabs template.

Once created you need to move into the app folder, you do this with the cd command (change directory), like so:

cd my-demo-app

Then run the following commands:

npm install
ionic serve

You will see a starter UI as shown below:

Ionic React Tabs Starter

You can see all available arguments that can be used with ionic start listed here.

Press Ctrl+C to stop the app.

Step 3: Create the WordPress REST API client

Now we need to create our Pages and the Components that will make the WordPress REST API client.

When using Ionic Angular adding pages and components to an Ionic project is quick and simple, we could do this using the following commands:

cd src/pages
ionic generate page Home

Unfortunately, this is not currently possible with the Ionic Cli when using React.

[ERROR] Cannot perform generate for React projects.
Since you're using the React project type, this command won't work. The Ionic CLI doesn't know how to generate framework components for React projects.

However, this shouldn’t slow down the sagacious developer, not with the plethora of modern AI code generators (ChatGPT, Bard, Copilot) eager and willing to assist.

Either create the new Home page and Home styles component (a blank .css file) by running the commands.

Mac OS Users:

touch src/pages/Home.tsx
touch src/pages/Home.css

Windows Users:
You should installĀ Windows Subsystem for LinuxĀ (WSL), to make life easier when working with WordPress locally. Then, type.

wsl touch src/pages/Home.tsx
wsl touch src/pages/Home.css

Or, for real simplicity just install touch-cli. To do this run:

npm install touch-cli -g

You can then use touch as per the Mac OS instructions.

Repeat this step for the Tab2 files to create your Posts view by running the commands:

touch src/pages/Posts.tsx
touch src/pages/Posts.css

Alternatively, simply rename both the Tab1 files to Home and the Tab2 files to Posts.

Now, open src/App.tsx and paste the updated code as shown below:

import { Redirect, Route } from 'react-router-dom';
import {
  IonApp,
  IonIcon,
  IonLabel,
  IonRouterOutlet,
  IonTabBar,
  IonTabButton,
  IonTabs,
  setupIonicReact
} from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import { home, reader, square } from 'ionicons/icons';

import Home from './pages/Home';
import Posts from './pages/Posts';
import Tab3 from './pages/Tab3';

/* 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';

/* Theme variables */
import './theme/variables.css';

setupIonicReact();

const App: React.FC = () => (
  <IonApp>
    <IonReactRouter>
      <IonTabs>
        <IonRouterOutlet>
          <Route exact path="/home">
            <Home />
          </Route>
          <Route exact path="/posts">
            <Posts />
          </Route>
          <Route path="/tab3">
            <Tab3 />
          </Route>
          <Route exact path="/">
            <Redirect to="/home" />
          </Route>
        </IonRouterOutlet>
        <IonTabBar slot="bottom">
          <IonTabButton tab="home" href="/home">
            <IonIcon aria-hidden="true" icon={home} />
            <IonLabel>Home</IonLabel>
          </IonTabButton>
          <IonTabButton tab="posts" href="/posts">
            <IonIcon aria-hidden="true" icon={reader} />
            <IonLabel>Posts</IonLabel>
          </IonTabButton>
          <IonTabButton tab="tab3" href="/tab3">
            <IonIcon aria-hidden="true" icon={square} />
            <IonLabel>Tab 3</IonLabel>
          </IonTabButton>
        </IonTabBar>
      </IonTabs>
    </IonReactRouter>
  </IonApp>
);

export default App;

Press Ctrl+S on a PC or Command+S on a Mac to save the file.

You may see an error saying Home or Posts cannot be found.
To resolve this we need to update the views within the pages directory.

Open src/pages/Home.tsx and paste the code below:

import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import HomePage from '../components/HomePage';
import './Home.css';

const Home: React.FC = () => {
  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Home</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
        <IonHeader collapse="condense">
          <IonToolbar>
            <IonTitle size="large">Home</IonTitle>
          </IonToolbar>
        </IonHeader>

        <HomePage />

      </IonContent>
    </IonPage>
  );
};

export default Home;

Save that. Then, open src/pages/Posts.tsx and paste the code below:

import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import WPPosts from '../components/WPPosts';
import './Posts.css';

const Posts: React.FC = () => {
  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>Posts</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
        <IonHeader collapse="condense">
          <IonToolbar>
            <IonTitle size="large">Posts</IonTitle>
          </IonToolbar>
        </IonHeader>

        <WPPosts />

      </IonContent>
    </IonPage>
  );
};

export default Posts;

And save.

Before we move on to testing our App works we also need to create our components (these are the reusable blocks of code that are loaded within a page).
To do this run:

touch src/components/HomePage.tsx
touch src/components/WPPosts.tsx

In order to fetch content from the WordPress REST API in Ionic React, you can use the native fetch API or libraries like axios to make the HTTP requests.

In this guide we’ll use axios so make sure you have axios installed in your Ionic React project by running:

npm install axios 

Once done, open src/components/HomePage.tsx and paste the code below:

import { useEffect, useState } from 'react';
import axios from 'axios';

interface Page {
    id: number;
    title: { rendered: string };
    date: string;
    modified: string;
    excerpt: { rendered: string };
    content: { rendered: string };
    featured_media: number;
    slug: string;
    status: string;
    type: string;
    format: string;
    sticky: boolean;
    template: string;
    comment_status: string;
    author: number;
    categories: number[];
    tags: number[];
}

const Page = () => {
  const [page, setPage] = useState<Page | null>(null);

  useEffect(() => {
    const fetchHomePage = async () => {
      try {
        const response = await axios.get(`${import.meta.env.VITE_WORDPRESS_URL}/wp-json/wp/v2/pages?slug=${import.meta.env.VITE_WORDPRESS_HOMEPAGE_SLUG}`);
        
        if (response.data.length > 0) {
          setPage(response.data[0]);
        }
      } catch (error) {
        console.error('Error fetching WordPress homepage:', error);
      }
    };

    fetchHomePage();
  }, []);

  return (
    <div className="ion-padding">
      {page ? (
        <>
          <h2>{page.title.rendered}</h2>
          <div dangerouslySetInnerHTML={{ __html: page.content.rendered }} />
        </>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
};

export default Page;

Save the file. Then open src/components/WPPosts.tsx, copy and paste the example code snippet below which demonstrates how to retrieve posts from the WordPress REST API in Ionic React:

import { useEffect, useState } from 'react';
import axios from 'axios';
import { IonButton } from '@ionic/react';

interface Post {
  id: number;
  title: { rendered: string };
  date: string;
  modifed: string;
  excerpt: { rendered: string };
  content: { rendered: string };
  featured_media: number;
  slug: string;
  status: string;
  type: string;
  format: string;
  sticky: boolean;
  template: string;
  comment_status: string;
  author: number;
  categories: number[];
  tags: number[];
}

const Posts = () => {
  const [posts, setPosts] = useState<Post[]>([]);
  const [showContent, setShowContent] = useState<boolean>(false);

  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await axios.get(`${import.meta.env.VITE_WORDPRESS_URL}/wp-json/wp/v2/posts`);
        setPosts(response.data);
      } catch (error) {
        console.error('Error fetching WordPress posts:', error);
      }
    };

    fetchPosts();
  }, []);

  const toggleDisplay = () => {
    setShowContent((prevState) => !prevState);
  };

  return (
    <div className="ion-padding">
      <h2>WordPress Posts</h2>
      <IonButton onClick={toggleDisplay}>
        {showContent ? 'Show Excerpt' : 'Show Content'}
      </IonButton>
      {posts.map((post) => (
        <div key={post.id}>
          <h3>{post.title.rendered}</h3>
          <small>{post.date}</small>
          {showContent ? (
            <div dangerouslySetInnerHTML={{ __html: post.content.rendered }} />
          ) : (
            <div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
          )}
        </div>
      ))}
    </div>
  );
};

export default Posts;

This demonstrates how to retrieve both a single page and posts content from the WordPress REST API in an Ionic React App.

In the above examples, we define functional components called Page and Posts which will fetch data from the WordPress REST API and render them on the screen. We use the useState hook to store the retrieved data in the posts state variable.

Inside the useEffect hook, we define an asynchronous function fetchPosts that uses axios to send an HTTP GET request to the WordPress REST API endpoint for posts. The response is then stored in the posts state variable using the setPosts function.

In the return statement, we map over the posts array and render the titles and content. The post.title.rendered and post.content.rendered properties are used to access the rendered HTML of the post’s title and content.

In the component examples given we have added a TypeScript interface called Post to describe the shape of a WordPress post. This interface includes the id, title, and content properties and other common properties available in the REST response data.

We use this Post interface to explicitly define the type of the posts state variable as Post[]. This informs TypeScript that the posts array should contain objects that match the Post interface structure.

By providing the correct type information, TypeScript should not complain about missing properties or display errors.

Adjust the interface according to the actual structure of the WordPress API response for posts if you have made any customisations to the REST response.

Do remember, you need to replace 'VITE_WORDPRESS_URL' with the actual URL of your WordPress site URL and 'VITE_WORDPRESS_HOMEPAGE_SLUG' with the slug of the page you want to use as the homepage

To do this create a new file called .env.local in the root of the project (see demo repo) and paste in the code below:

REACT_APP_WORDPRESS_URL=
REACT_APP_WORDPRESS_HOMEPAGE_SLUG=

# Update these values to match your actual config, example below
# REACT_APP_WORDPRESS_URL=/
# REACT_APP_WORDPRESS_HOMEPAGE_SLUG=homepage

Now let’s check our app:

ionic serve

Step 4: Add Splash Screens and Icons

To do this, Install Capacitor Assets

Capacitor Assets is used to generate icons and splash screens for all platforms.

Run:

npm install @capacitor/assets --save-dev

If you’d rather download the demo code for this tutorial.

View the completed demo in the GitHub repo, or;

In your local development directory run:

git clone https://github.com/primitive/astral-wordpress.git
cd astral-wordpress && npm install

Then, to run your app in development mode, use:

ionic serve

Resources and Further Reading

GET IN TOUCH

Shaun Knowles
Shaun Knowles
Wrote this on
Categrised as:
DevelopmentInteractive MediaTechnologyTutorialWeb Design

Tagged#HowTo


More Articles

Cover Image for How to Check and Update Your Git Version

How to Check and Update Your Git Version

Change is inevitable and, in the technical world, usually beneficial. Keeping your Git installation up to date is highly recommended, it gives you all the latest features, improvements, bug fixes, and more. Let’s see how to check which Git version you’re currently using and how to update it to the latest version. To stay up […]

Read More… from How to Check and Update Your Git Version

Shaun Knowles
Shaun Knowles
Cover Image for Next Generation Eco Friendly WordPress Websites

Next Generation Eco Friendly WordPress Websites

Do you want a WordPress website that is truly unique and reflects your brand? We design and build high performance websites for all purposes. […]

Read More… from Next Generation Eco Friendly WordPress Websites

Shaun Knowles
Shaun Knowles