Build a Mobile App With Ionic + WordPress

Learn how to build a mobile app that integrates Ionic with WordPress.
This project includes:

  • Ionic 3.9.2, WP-API v2 integration
  • WP-API post integration with pull to refresh and infinite scroll
  • Simple login and membership functionality
  • WooCommerce REST API v2 with Stripe payments
  • More coming soon…

View on Github
This project is mostly for fun, and so other developers can get excited about Ionic. The app includes a posts page with pull to refresh and infinite scroll, a login with custom authentication (requires a plugin), static page, tabs menu, and more coming soon.
You can use this project as a starting point to create a mobile app of your own.

WordPress integration

This app uses the WP-API to integrate with WordPress. Your site must be running WordPress 4.7 or later, or you have to install the WP-API v2 plugin.
You’ll need Ionic’s CLI tools, and to use the login feature you have to install my WordPress plugin. The plugin adds a WP-API endpoint to handle logging in and out, and adds featured image urls to the post response.

How to use

  1. Clone the git repository, run npm install
  2. Change 2 urls and the security passphrase in the app files (instructions below)
  3. Change the security passphrase in the WordPress plugin (instructions below)
  4. Install the WordPress plugin on your test site
  5. Run ionic serve to test in a browser

Change URLs and Passphrase

Before you use this project, you’ll need a WordPress site to connect the app.
After you clone the WP Ionic repository, open providers/configure/configure.ts and change the website url. For the post list, you can use any WP-API endpoint, including a custom endpoint (like a CPT) and url parameters.
Next, open providers/login/login.ts and change the security passphrase. It looks like this:
[html]formData.append(“security”, ‘my-secure-phrase’);[/html]
You’ll need to change the security passphrase in the WordPress plugin to match (sb-app-integration/inc/class-wpapi-login.php around line 43).
This passphrase simply stops anyone from being able to try to login through this endpoint. It’s not the most secure thing in the world, but this is basically just a login form. It doesn’t do anything except log a user in, it does not expose any sensitive data.
You should always perform login over SSL. Do your own homework on security.

How the Login Works

The SB App Integration plugin adds an endpoint to the WP-API to allow a simple verification of a WordPress user.
Here’s how it works:

  1. We send a POST request to a WordPress site from the app with user, pass, and security phrase.
  2. If it all checks out, we do a wp_signon() (which just gives us a cookie) and return successfully
  3. The app checks the response and saves the user data if we logged in
  4. We also log out the same way, but sending logout=true with the POST request

Since we are saving the login data in the app, we can show and hide members only content based on the login status.
To make this all happen, we need the SB App Integration WordPress plugin that handles the user verification.
The information below is already handled in the plugin and app files, it’s just for informational purposes if you want to customize.
Once the plugin is activated, you can make a POST request to
Include the following:

  • $_POST[‘security’] is the security phrase
  • $_POST[‘logout’] if set to “true” it will log the user out
  • $_POST[‘username’] or $_SERVER[‘PHP_AUTH_USER’] (not all servers accept authentication headers)
  • $_POST[‘password’] or $_SERVER[‘PHP_AUTH_PW’] (not all servers accept authentication headers)

Be sure to change the security passphrase in class-wpapi-login.php, preferably a hash of some sort.
If a valid username, password, and security phrase is sent, a json success message will be returned to the app:
$return = array(
‘message’ => ‘Login successful!’,
‘username’ => $info[‘user_login’],
‘success’ => true
The app then saves the login data using Ionic Storage. You can check if a user is logged in by getting the data from storage. For example:
[html]‘user_login’).then( data => {
if( data ) {
this.loggedin = true
} else {
this.loggedin = false
Login Notes

  • You can use an authentication header to do this instead of a normal POST request, but many servers do not accept auth headers.
  • CORS is always an issue, which is why we have the Access-Control-Allow-Origin header in there.
  • The plugin does a wp_signon(), which will add the logged in cookie to the browser. Technically you can load the site in an iframe and view it logged in now, but this won’t work if you switch to the in app browser. WKWebview also has an issue with cookies, so you may need to use UIWebview if you are going native.
  • We aren’t doing much of a security check, but the only thing an attacker could do here is login. Let me know how you’d improve security in the comments.

WP-API Modifications

This plugin also adds featured image urls to the post response to make it easier to display features images in post lists. The field added is featured_image_urls, with all available urls for each image size returned.


WooCommerce REST API
To use the WooCommerce module, you must create a REST API key in WooCommerce.
In the app, go to providers/configure/configure.ts and change the Authorization header. This is a base64 encoded string of your consumer key and secret. You can generate these using btoa(key:secret), but keep in mind these are discoverable in your app files even in a signed native app package.
Included features:

  • Product list
  • Single product pages
  • Add to cart
  • Cart modal
  • Basic multi-step checkout
  • Stripe Payments

You can now create payments with Stripe, select shipping zones, and add variable products to the cart.

Stripe Payments

To use Stripe payments with the WooCommerce REST API, open src/app/app.module.ts and change the publishable key around line 30. You can get your Stripe API keys here.

Customizing the App

To run the app, clone the WPIonic git repository, then run npm install.
You can add a page or provider using Ionic CLI commands like:
ionic generate page MyPage
To add an item to the tab menu, open tabs.html and tabs.ts and add your pages as needed.
Have fun, and send me some pull requests!

  • 3/15/18: Add to cart improvements, configure provider for easier setup
  • 3/10/18: Added Stripe payments, shipping zones, and better variable products!
  • 2/27/18: Added simple WooCommerce product display through the REST API
  • Update 2/26/18: wpIonic has been completely re-written and updated for Ionic 3.9.2. I also added a fully functioning login system.
  • Update 9/15:wpIonic has been modified to work with the WP-API version 2. I’ve also added new features such as post caching and bookmarks. Follow the project on Github for the most recent updates.
  • Update 12/15: I wrote a new article on the Ionic blog about creating an app with Ionic 2 and the WP-API 2. Check that out here.






45 responses to “Build a Mobile App With Ionic + WordPress”

  1. hdp Avatar

    how to use the custom post type to this

      1. hdp Avatar

        tks, how to give a leaving words function? and the search function

  2. ng-noob Avatar

    This is seriously great.
    I already have a custom version of WP API running that is being used by a different app so I can’t get rid of it. How would you go about using your version with regular WP API (without Reactor)?
    I could really use the most basic version without reactor in order to be able to tweak it and get it to work with my current setup.

    1. ng-noob Avatar

      …and with regular json instead of jsonp/callback

      1. Scott Avatar

        This app is setup to use jsonp, you could probably get it to work with json but you may run into some CORS problems.

        1. ng-noob Avatar

          Thanks. I was able to get it to work with just json by setting CORS header on server.

  3. Mark Dix Avatar
    Mark Dix

    Hi Scott
    Great Tut.
    I have followed everything and it all works until I add a custom controller to the new custom page. When I add the controller to teh state in app.js it causes the App as a whole to display blank. When I coment it out ot works again.
    I have created other Apps using Ionic and cant see where I am going wrong. Is there an a known issue or more likely I have done something wrong.
    Thanks in advance

    1. Scott Avatar

      Hi Mark, it’s most likely a syntax error, maybe an extra semi colon or something. Take a look at how the other states/controllers are laid out, and make sure yours is the same. You can use the browser console to debug.

      1. Mark Dix Avatar
        Mark Dix

        Hi Scott
        Thanks very much for your reply.
        I have followed the way the other states and controllers are laid out, unfortunately with the same issue. I have never seen this isue with my other Apps. This is my state:
        .state(‘app.custom2’, {
        url: “/custom2”,
        views: {
        ‘menuContent’: {
        templateUrl: “templates/custom2.html”
        controller: ‘Custom2Ctrl’
        I am getting the following error:
        Error: [$injector:modulerr] Failed to instantiate module wpIonic due to:
        [$injector:nomod] Module ‘wpIonic’ is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument
        Would you by any chance know what the issue may be?
        Many thanks

      2. Mark Dix Avatar
        Mark Dix

        Hi Scott
        Apologies it was the apostrophes from copying and pasting from the web.
        My bad and very frustrating.

  4. Mark Dix Avatar
    Mark Dix

    Hi Scott
    Would I be right in saying that you can only have one $rootScope.callback value if you want to pull custom posts.
    I have added a new $rootScope.callback to a new controller but it seems to get confused pulling one callback value and then the other depending on where and when I refresh my page within my App.

    1. Scott Avatar

      Hi Mark, yes if you use $rootScope it’s basically a global. You’d want to use $scope.myVar instead of $rootScope.myVar if you just need it defined in your controller.

  5. Silas Avatar

    Hi Scott,
    thanks a lot for this great work.
    I see the posts from my WordPress Site, but i cannot login.
    My console in my “ionic serve” view shows: “Error: targetFrame.postMessage is not a function”
    I dont understand how the login should work. Do have to compile the Project with Phonegap and not with ionic. are there any difference?
    Could you help my with an example?
    How could this ( custom Auth Plugin help me to make targetFrame.postMessage a function?
    Do i need this Plugin (
    sorry for my english and maybe a stupid question 😉

    1. Scott Avatar

      Hi, the login is just an example, it does not actually work. Authentication is complex, so I probably won’t be adding that to wpIonic. You can use Reactor to build an app with a login.

  6. venis Avatar

    Please help me to fix this issue
    I have build ionwordpress android apk but when i viewed it on my emulator, it shows me the workpress homepage ( recent post page ) with no posts displayed and the page was overlayed with “Loading posts…”. and never loads any posts
    Intially i have removed the login and register for controller as per documentation since i don’t require it for my wordpress site.
    Please help me to fix this issue

    1. David Castro Avatar

      @venis, did you look at the browser’s console logs? If you can paste them into a follow-up, that might be helpful. Even better, if you can provide a URL for the app you’ve created, then viewers of this page can look at your actual code and possibly help you resolve your issues.

  7. shayari Avatar

    Thanks a ton. I was searching for a IONIC WP tutorial. Thanks for the awesome tutorial.

  8. nonsense Avatar

    Have you ever try to build a mobile app with woocommerce integration?

    1. Scott Avatar

      Yes, both Reactor and AppPresser have WooCommerce integrations.

  9. Ed Avatar

    Hi Scott.
    Thanks for the great tut.
    I see a line of code that was commented out:
    I uncommented the line, but I am still not seeing any featured images showing up.
    Could you please give us a pointer as to how you display featured images?

    1. Scott Avatar

      Hi Ed, version 2 of the WP-API doesn’t have a good way to do that yet. I’m waiting for them to resolve this issue, but until then you’ll have to use your own custom code. See this ticket:

      1. Ed Avatar

        Hi Scott.
        Ahhh that seems like a massive oversight :O
        Many thanks I followed that link, but the code doesn’t really have any context for me… Where would I put that (what looks like PHP) code?
        I’m a total WordPress and this WP-API noob (I’m an Ionic user which is how I got here).
        Any help would be massively appreciated.
        Thanks Scott.

  10. M M Avatar
    M M

    Hi scott, thanks for that great tut,
    i am facing one issue is when any post is clicked it loads the content, but the loading icon always stays there and make the whole screen unclickable. could you please assist.

    1. skating Avatar

      how to solve this issue?

  11. Kevin Avatar

    I love the tuturoial. I am really digging ionic a lot.
    One question, I have the feed for post all set up but when I compile and send it to the ipad, it loads fine, but when I acutally click into a post I get a endless loop. The spinner comes up (with the box around it) and everything becomes unresponsive. Is it something my wordpress install is doing or is the code not functional out of box?

  12. DW Avatar

    Would this sample work with another WordPress API, for example?

    1. Scott Avatar

      No, but you could customize it to work with that. Not sure why you would use that plugin instead of the rest api that’s going into WordPress core?

  13. Luke Burford Avatar

    Also have the issue with the spinner stuck as soon as I view a single post. Can only get out of the single view by using the browser back button, and the spinner remains in place, making the actual window unresponsive.
    Here it is:
    Otherwise this is pretty great 🙂

  14. Erik Thiart Avatar

    Hi scott, thanks for this tutorial. I have the exact same issue as these last few guys.
    When certain posts is clicked it loads the content, but the loading icon always stays there and make the whole screen unclickable.
    Do you have any idea how to prevent this?
    Best would be to just see it for yourself if you are on android just search “ForeverHuman” it’s the app, it has a picture of a cat, since the wordpress blog is about cats.
    I love cats
    Anyhow, if you could possibly assist with this situation I will be forever great full.

    1. Scott Avatar

      Hi, I’m not seeing this issue in my app. Make sure you are using the WP-API v2, not version 1, and no plugins are conflicting. You can use your browser console to see any errors to help you debug.

      1. Erik Thiart Avatar

        Hi Scott, if it’s not to much to ask, just download my app from the store quickly, it’s your app I only added my wording to it nothing else.
        On WordPress I use the version 2 wp-api plug in.
        I also disabled jet packs json api extention. If that makes sense.

      2. Erik Thiart Avatar

        This is the plug in I am using ->
        This is the website ->
        This is the App ( android ) ->
        I really want to use this so badly, I’m just stuck as I do not have the technical knowledge as to what the issue might be?
        I also noticed when I went to phonegap to compile the app it gives the following message:
        Can’t recall by heart, but it is something like the app is not using the latest version of something and should be 5.1.1

  15. yondi hardian Avatar

    Hi scott, thanks for this great tutorial . I have installed plugin on my wordress and change $rootScope.url to my website, but on /app/posts posts doesn’t show, when i check on firebug the request api is going well but not on javascript DOM->JAVASCRIPT like using your website url.
    Thanks a lot.

  16. Michael Spredemann Avatar
    Michael Spredemann

    I followed the instructions, but am not seeing any posts. I can browse to /wp-json/wp/v2/ on my site and see the json data. I’m not getting any errors in my console or server errror logs. The site is running locally on my PC. Could that be an issue?

    1. Scott Avatar

      I’m going to rewrite the services, stay tuned.

      1. Michael Spredemann Avatar
        Michael Spredemann

        Excellent. Thank you for sharing your work.

  17. Sagar Avatar

    Posts are not loading.
    Any updates on this…
    Thanks in advance

    1. Michael Spredemann Avatar
      Michael Spredemann

      See Scott’s reply to my question about the same thing. He is working on it. I see in the git repository that he made some new commits on December 3rd, but I haven’t done a pull and tested yet.

  18. Saddam Hossain Avatar

    Thanks very much for this nice work Scott. And, thanks again for sharing it.

  19. Gaël Corna Avatar

    Hi Scott, it’s really one of the clearest posts i read and the app works great but only on my pc. I installed it on an android phone and no post are loading. I’m really not understanding why. Is there someting about authentication ?
    Thanks in advance

  20. Gaël Corna Avatar

    Hi Scott. Got a solution to my problem: i add the ng-csp directive in the html tag and all works fine now.

    1. Ndugus Avatar

      share Please

  21. Den Bagus Avatar

    hello scott, i have problem, can’t load image-feufeatured,

  22. Hakan Goker Avatar
    Hakan Goker

    Hi Scott. I have a problem with sb-app-integration/inc/class-sb-woocommerce.php. The token on app side works well. I can get the token but when I pass the token, the order id and data to php page/plugin then I am getting error from stripe. The intent is giving error. The provided source has already been used to make another payment. You cannot reuse sources without attaching them to a Customer object first.”, I assume it is expcting cutomerID created from stripe. I have added $_POST[‘stripe_customer_id’] = $stripeCustomer_id; tot he plugin but the page is not pushing exactly or there is something wrong with wc scripts. cant understand whats happening. If you are willing to help I can send more information. thx