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:
- Volta JavaScript Tool Manager (optional but recommended)
- Node.js and npm (Node Package Manager) installed
- Git version manager
- A code editor installed (Visual Studio Code) or use of an online editor (Phoenix / Stackblitz)
- A WordPress website (if you’re not sure how to do this, check the WordPress setup guide)
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:
- Open your terminal or command prompt
- 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:
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=https://get2.sknow.it
# 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
- Ionic Docs
- IonicĀ UI components
- Ionic VS Code Extension