Ionic Wordpress Integration

If you want to access your WordPress site's data through a mobile app, then this tutorial is for you! This step by step ionic tutorial will show you how to connect your ionic app with the Wordpress REST API in order to be able to pull your site's data. Also, we will show you how to allow users to create new comments and how to authenticate them using JWT (Json Web Tokens).

In this ionic tutorial, we will walk you through the process of creating an Ionic app that pulls WordPress posts and other content using the WP REST API.

If you are new to Ionic, I strongly recommend you to first read our Introduction to Ionic tutorial. It will help you understand some of the key components of this powerful framework.

At IonicThemes we are big fans of Learning by example, that's why all our ionic tutorials include a complete and free ionic starter app that you can reuse in your ionic projects. We strive to create the best content for Ionic Framework, both tutorials and templates to help the Ionic community succeed.

Without further ado, this is the app we are going to build in this tutorial.

ionic wordpress login
ionic wordpress sign up
ionic wordpress integration
ionic wordpress integration
ionic wordpress integration
ionic wordpress starter app

We will discuss the implementation of the following features:

  • Show all published posts
  • Show all the information of a specific post
  • Show the comments and categories related to a post
  • Query posts by category
  • Authentication using JWT
  • Use infinite scroll to paginate the posts

You can download all the source code of this ionic wordpress free template by clicking the GET THE CODE button from above. Also, you can check the online demo.

Wordpress REST API

The REST API is included in the Wordpress Core from WordPress 4.7. Plugins are no longer required, just install the latest version of WordPress and you're ready to go.

In order to make sure you are able to make requests to the Wordpress REST API you only need to make a request to the following url: http://YOUR-WORDPRESS-SITE/wp-json/wp/v2/ and you should see something like this.

Please note that you need to replace YOUR-WORDPRESS-SITE with your own value.

What is Wordpress REST API?

The WordPress REST API provides API endpoints for WordPress data types that allow developers to interact with sites remotely by sending and receiving JSON. This enables developers to create, read and update WordPress content from client-side JavaScript or from external applications.

If you are new to WP REST API, I would suggest you to go through the Key Concepts.

Get Wordpress posts into your ionic app

We are ready to start pulling data from your wordpress site into your ionic app. We will start by requesting a list of your recent posts.

In order to get a list of your recent posts you need to make an http request to the following endpoint: http://YOUR-WORDPRESS-SITE/wp-json/wp/v2/posts. This will return a json with the 10 latest posts of your blog.

Going to our ionic wordpress app code, we created an angular service that we named WordpressService that holds all the communication with the Wordpress REST API. Here you can find all the methods that we will use to get the content of our blog.

The following getRecentPosts() method from the WordpressService will return an observable with the first 10 posts that match the previous query.

getRecentPosts(categoryId: number, page: number = 1) {
// if we want to query posts by category
let category_url = categoryId? ("&categories=" + categoryId): "";

return this.http.get(
	environment.wordpress.api_url
	+ 'posts?page=' + page
	+ '&orderby=modified' // order by last modified date
	+ category_url)
}

categoryId is an optional parameter that you can use if you want to get the posts from a specific category.

WORDPRESS_REST_API_URL is a value that we defined in src/environments/environment.ts with the url of our Wordpress API. You should change this with your own url in order to get the posts from your Wordpress blog.

As a good practice, we use Angular Resolvers to resolve the data of a specific route. They enable us to pre-fetch data from the server before navigating to a route. This way, the data is ready the moment the route is activated.

Click to tweet

Learn more about angular resolvers and how to use them in an Ionic app in this guide about Ionic Navigation and Angular Routing.

So, we have a PostsResolver in src/app/posts/posts.resolver.ts where we subscribe for the observable result in order to get the posts list. Once the route resolver has the data available, he will pass it through to the end route, in our case is the posts route.

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { WordpressService } from '../services/wordpress.service';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class PostsResolver implements Resolve<any> {

  constructor(private wordpressService: WordpressService) { }

  resolve(route: ActivatedRouteSnapshot): Observable<any> {
    const categoryId = route.queryParams['categoryId'];
    const categoryTitle = route.queryParams['title'];

    return this.wordpressService.getRecentPosts(categoryId)
    .pipe(
      map((posts) => {
        return { posts, categoryTitle, categoryId };
      })
    )
  }
}

Now, we should subscribe to the result of the resolver from the PostsComponent so, in our src/app/posts/posts.page.ts we will add the following code inside the ngOnInit method.

ngOnInit() {
  this.route.data.subscribe(routeData => {
    const data = routeData['data'];

    this.posts = data.posts;
    this.categoryId = data.categoryId;
    this.categoryTitle = data.categoryTitle;
  })
}

On the code above, we subscribe to the result of the resolver and because we are using Angular resolvers, we can make sure that the data will be ready once the route is activated.

It's also important to mention that we should declare the resolver in our PostsModule.

const routes: Routes = [
  {
    path: '',
    component: PostsPage,
    resolve: {
      data: PostsResolver
    },
	 runGuardsAndResolvers: 'paramsOrQueryParamsChange' // because we use the same route for all posts and for category posts, we need to add this to refetch data
  }
];

Now that we have our blog posts ready, we need to choose which Ionic components we will use to display them in our app. For this example we chose to show the post information with a IonCard.

The following code is located in posts.page.html. We simply iterate through the posts list.

<ion-card *ngFor="let post of posts" [routerLink]="['/post', post.id]" class="post-card">
  <ion-card-header>
    <ion-card-title [innerHTML]="post.title.rendered"></ion-card-title>
  </ion-card-header>
  <ion-card-content>
    <p [innerHTML]="post.excerpt.rendered"></p>
  </ion-card-content>
  <ion-item class="ion-activated" detail lines="none" color="secondary">
    <ion-label *ngIf="!post.modified">{{post.date | date}}</ion-label><ion-label *ngIf="post.modified">{{post.modified | date}}</ion-label>
    <ion-label class="read-more-label">Read More</ion-label>
  </ion-item>
</ion-card>
ionic wordpress integration

Posts pagination with infinite scroll

In order to improve the Ionic app performance and UX, we added pagination to this Ionic Wordpress example app. There are different ways to implement pagination and here we decided to use Ion Infinite Scroll component.

To add infinite scroll to this Ionic app we need to add the following code in our posts.html file just after the </ion-card>.

<ion-infinite-scroll (ionInfinite)="loadData($event)">
  <ion-infinite-scroll-content
  loadingSpinner="bubbles"
  loadingText="Loading more posts ...">
  </ion-infinite-scroll-content>
</ion-infinite-scroll>

The expression assigned to the ionInfinite event is called when the user reaches the bottom of the page. So, we need to calculate the number of the next page and request the posts for that page.

By default, Wordpress API gets 10 post per page when we call the /posts endpoint. If you want to change this, check the Wordpress API documentation.

So, going back to our loadData($event) method, we will simply call this.wordpressService.getRecentPosts(this.categoryId, page) where page is the number of the next page. We then subscribe to the result of this method (it returns an Observable) and assign this next 10 posts to the list of the current posts.

loadData(event: any) {
  const page = (Math.ceil(this.posts.length / 10)) + 1;

  this.wordpressService.getRecentPosts(this.categoryId, page)
  .subscribe((newPagePosts: []) => {
    this.posts.push(...newPagePosts);
    event.target.complete();
  }, err => {
    // there are no more posts available
    event.target.disabled = true;
  })
}

If we make a request with a page number that is not valid, it means we reached the last page, so we will disable the infinite scroll from actively trying to receive new data while scrolling. There aren't any more pages available so the infinite scroll is no longer needed.

If you want to start creating your Ionic Framework app but don’t know how to start, I suggest your to try Ionic 5 Full Starter App. It's an Ionic Angular app that you can use to jump start your Ionic Framework development and save yourself hundreds of hours of design and development.

It includes more than 100 carefully designed views and components. It has full support for PWA and a complete and detailed documentation that will help you setting everything up in no time.

Get post information

In the previous section, we explained how to get the list of posts from our Wordpress blog into our Ionic framework application. We also want to be able to show the details of each post. In order to achieve this, we will create another route and another component. This new route will receive as a route parameter, the ID of the post to be expanded.

In this project we use lazy loaded routes so we need a routing file specific to each module to define the module routes.

In our main routing file AppRoutingModule we will add the following code:

{
	path: 'post/:id',
	loadChildren: () => import('./post/post.module').then( m => m.PostPageModule)
}

And then, we will create our new PostPageModule. Please note that you can handle all the boilerplate generation using the Ionic CLI.

Post Details Page

The new Ionic page will render the following data from our Wordpress posts:

  • Title
  • Content
  • Author
  • Date
  • Categories
  • User comments

For this route we will also use an Angular Resolver to fetch the data of a specific post. Then, from the PostPage, we'll subscribe for the observable result in order to render the post information.

The PostResolver needs to make multiple requests to the Wordpress API because this route needs data that's avialable from different API endpoints.

resolve(route: ActivatedRouteSnapshot): Observable<any> {
  const id = route.paramMap.get('id');

  return this.wordpressService.getPost(id)
  .pipe(
    concatMap((post: any) => {
      const author = this.wordpressService.getAuthor(post.author);
      const categories = this.wordpressService.getPostCategories(post);
      const comments = this.wordpressService.getComments(post.id);

      return forkJoin({ author, categories, comments })
      .pipe(
        map(postData => {
          return {...postData, post};
        })
      )
    })
  );
}

The Wordpress REST API has different endpoints that we should ping in order to get the authors data, the post categories and the post comments. That's why on the previous code you can see that we have one observable per API call. All these observables are wrapped inside a forkJoin, this means that we will wait untill all of them are ready in order to continue. This is because we want to wait for all the data to be ready before displaying anything.

PRO TIP! You can take a different approach here and use our app shell components to build a progressive route transition like we explain on this Ionic navigation tutorial.

The behavior will be something like this:

app shell navigation

Note that on this is a non-blocking approach to use in our Angular route resolvers which provides a much better user experience.

We created a series of app shell elements for Ionic that will help you building a variety of UIs that progressively translate from the shell model loading state to the final state displaying real data. Feel free to reuse this elements on your Ionic projects. You can download them by clicking the GET THE CODE button from our Ionic Angular navigation guide.

We also use the RxJS operator concatMap because we need to wait for the getPost() observable to complete before requesting the author, categories and comments details.

To paginate the comment list we also use Ionic infinite scroll component.

Get wordpress posts by Category

On this Ionic Wordpress tutorial we will also explain how to get the posts from a specific Wordpress category.

When you click on a category badge, like shown on the screenshot below, we use the Angular RouterLink to navigate to the posts route with some additional query parameters that indicate we want to see the posts of a specific category.

ionic wordpress integration
ionic wordpress integration
<ion-badge class="post-category" color="secondary" *ngFor="let category of categories"
	[routerLink]="['/posts']" [queryParams]="{ categoryId: category.id, title: category.name}">
  {{category.name}}
</ion-badge>

Remember the code for the PostsResolver we saw earlier?

@Injectable()
export class PostsResolver implements Resolve<any> {

  constructor(private wordpressService: WordpressService) { }

  resolve(route: ActivatedRouteSnapshot): Observable<any> {
    const categoryId = route.queryParams['categoryId'];
    const categoryTitle = route.queryParams['title'];

    return this.wordpressService.getRecentPosts(categoryId)
    .pipe(
      map((posts) => {
        return { posts, categoryTitle, categoryId };
      })
    )
  }
}

The first two lines from the resolve() method check if there is any query parameter for the category. So, when we click on the "Tutorials" badge from the screenshot above, the app will navigate to http://localhost:8100/posts?categoryId=55&title=Tutorials

. Then, the PostsResolver will get excecuted and it will indicate our WordpressService to make an API call to the Wordpress API with the categoryID "55".

Ionic Wordpress Authentication

If you want to allow your users to comment on your posts, you need to add Wordpress authentication to your Ionic Framework app. I have to admit that this can be a bit tricky to implement because it has some sort of advanced configurations. But, don't worry, we will do our best to explain the required steps in this ionic wordpress tutorial.

To add Wordpress authentication to an Ionic app we will use JWT Authentication for WP REST API plugin. This plugin extends the WP REST API using JSON Web Tokens Authentication as an authentication method.

The first step to use this plugin is to carefully follow all the configuration instructions from the documentation, paying special attention when editing your .htaccess file.

JSON Web Token (JWT)

JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. The information involved is digitally signed which means it can be verified and trusted.

Why we need JSON Web Tokens? Authorization is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the token, allowing the user to access routes, services, and resources that are permitted with that token.

In this Ionic Wordpress tutorial, we will use JWT to add a comment to a post as we only want to allow authenticated users to be enabled to comment.

For more information about JWT check this Introduction to JSON Web Tokens.

Wordpress Login

After doing all the configurations explained here, let's see how to add the log in functionality to our Ionic framework application. Once the plugin is activated, a new namespace /jwt-auth/v1 is added. Also, two new POST endpoints are added to this namespace:

  1. /wp-json/jwt-auth/v1/token
  2. /wp-json/jwt-auth/v1/token/validate

The first endpoint validates the user credentials, this is username and password, and if the credentials are OK it will return an authentication token that we should use in future requests to the API. It will return an error if the credentials are incorrect.

The second endpoint simply validates if a specific token is still valid (not expired).

Once you get the token, you need to store it somewhere in your Ionic application, such as in a cookie or using localstorage.

The wp-api-jwt-auth will intercept every call to the server and will look for the Authorization Header, if the Authorization header is present, it will try to decode the JWT and will set the user according with the data stored in it.

To enable a user to log in to our Ionic app with their Wordpress credentials, first we need to authenticate him, and then save his data and token to the Local Storage (so we can retrieve it later).

On this Ionic Wordpress tutorial, we will use Capacitor Storage API to save and retrieve the token.

In our Ionic example app, we created an AuthenticationService where we put all the methods related to the authentication of the application. In this service, you will find the following method which tries to authenticate a user:

doLogin(username: string, password: string) {
  return this.http.post(environment.wordpress.auth_url, {
    username: username,
    password: password
  })
}

Note that environment.wordpress.auth_url is a constant defined in src/environments/environment.ts and in our case the value is https://wordpress.startapplabs.com/blog/wp-json/jwt-auth/v1/token.

We have a basic authentication form with username and password and once the user clicks on the Log In button, the code above gets called.

ionic wordpress login

Forms are a very important part of applications. You can use forms to perform countless data-entry tasks such as: login, submit a request, place an order, post content, or create an account. Learn everything about Ionic forms and input validations in Ionic apps.

If you are looking for a polished user interface and you want to save time by getting a ready made Ionic starter app which includes lots of forms and validation examples you should definitely check Ionic 5 Full Starter App.

These are some of the forms you can find in this Ionic Froms Starter. There are also more complex forms such as beautiful filters, ratings, validations, and many more!

Ionic 5 forms example
Ionic 5 forms example
Ionic 5 forms example

If the credentials entered by the user are correct, our doLogin() method returns an Observable with an object with the user details such as token, user photo, user email, and user display name.

Now, we can save the data of the logged user to the local storage using the Capacitor Storage API.

Our log in page has a canActivate angular route guard that checks if there is a user already logged in and in that case it will validate if the token is still valid. If the token is still valid, the user will navigate to the Posts page. If there isn't a logged in user or if the token is expired, we will redirect the user to the Login Page.

export class LoginGuard implements CanActivate {

  constructor(
    private authenticationService: AuthenticationService,
    public router: Router
  ) {}

	canActivate() {
		return from(this.authenticationService.getUser())
    .pipe(
      concatMap(user => {
        if (user) { // user is the value returned from the local storage
          return this.authenticationService.validateAuthToken(JSON.parse(user).token)
            .pipe(
              catchError(error => of(error)),
              map(result => {
                if (result.error) {
                  // token is expired
                  return true;
                }
                else {
                  // user is logged in and token is valid
                  return this.router.parseUrl('/posts');
                }
              })
            )
        } else {
          // there is no logged user
          return of(true);
        }
      })
	  );
	}
}

Then in our Authentication Service we have the method to validate the authentication token.

validateAuthToken(token){
  let header : HttpHeaders = new HttpHeaders({'Authorization': 'Bearer ' + token});
	return this.http.post(environment.wordpress.auth_url + '/validate?token=' + token,
		{}, {headers: header})
}

Register new user

We will not get into details here, but there's an important thing to mention. Only authenticated and authorized users are allowed to register new users. This means that you need to make an authenticated request and you should have permissions to create new users, for example your needs to be an Administrator. You can learn more in the plugin documentation.

Add a comment to a post

In order to add a comment in a Wordpress post a user must be logged in, this means that on the comment request we have to send the user authentication token.

As mentioned in the previous step, we saved the token of the logged user in the Local Storage, so we only need to retrieve it from there and then call the correct WP REST API endpoint.

The code to create a new comment is in post.page.ts file. We first check if there is a logged user saved in Local Storage using the Capacitor Storage API. If there is a logged user, then we allow him to create a new comment; otherwise, we show the user a message asking them to log in.

async createComment() {
  const loggedUser = await this.authenticationService.getUser();

  if (loggedUser) {
    let user = JSON.parse(loggedUser);

    // check if token is valid
    this.authenticationService.validateAuthToken(user.token)
    .pipe(
      catchError(error => of(error)),
      map(result => {
        if (result.error) {
          // token is expired
          this.openLogInAlert();
        }
        else {
          // user is logged in and token is valid
          this.openEnterCommentAlert(user);
        }
      })
    ).subscribe()
  } else {
    this.openLogInAlert();
  }
}

Wrapping up

On this Ionic Wordpress integration tutorial we explained how to connect your Ionic app with your WordPress blog. We saw how to list your WordPress posts with all their details, tags, categories and comments. Also, we explained how to add wordpress authentication to your Ionic app and the feature to allow your users to comment on your posts.

Wordpress is a powerful content management tool so having the ability to show the content from our blog into a mobile app is a great option. You can build an entire app based on the content from your blog. Also, you could add a side menu or tabs navigation (or even both) with the main categories of your content. If you need help adding side menu and tabs navigation to your ionic app, check Ionic 5 Full Starter App.

I hope you now have a better understanding of how to integrate wordpress to your ionic project. Remember you can download for free all the source code of the ionic demo app we built for this tutorial. You can use this demo app as a starter project to build your own Ionic framework app.

If you have any questions or comments please leave a message below, I would love to know your thoughts about this post.

Keep learning Ionic Framework

We have lots of tutorials and example apps that you can use to learn Ionic.

We also create complete Ionic mobile templates that will help you getting a real app up and running fast by handling all the boilerplate and design that normally takes weeks.

As Max Lynch, the CEO of Ionic Framework said: "Any Ionic developer should consider getting one and getting to work that much more quickly!"