How to create Mobile games & PWA with Ionic 4 and Phaser
Tags: ionic, phaser, pwa, games
Published: 2019-09-17 17:51:11

<main role="main"><article class=" u-minHeight100vhOffset65 u-overflowHidden postArticle postArticle--full is-supplementalPostContentLoaded is-withAccentColors" lang="en"><div class="postArticle-content js-postField js-notesSource editable" id="editor_6" g_editable="true" role="textbox" contenteditable="true" data-default-value="Title
Tell your story…" spellcheck="false"><section name="2ed1" class="section section--body section--first section--last"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><blockquote name="56a0" class="graf graf--blockquote graf-after--figure is-selected"><strong class="markup--strong markup--blockquote-strong">You can find the complete code in the</strong><a href="https://store.enappd.com/product/ionic-phaser-game-framework-ionic-4/"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--blockquote-strong"> Ionic 4 Phaser Starter</strong></a></blockquote><p name="346c" class="graf graf--p graf-after--blockquote">Ionic platform has become one of the big names in app development in recent years. Moving from Ionic 1 to 4 in past few years, Ionic has not just gained popularity, but also improved its robustness and reliability. Today, Ionic framework is one of the easiest to make an android or iOS app with, and also Progressive web apps. 🚀</p><p name="2357" class="graf graf--p graf-after--p">Phaser, first released in 2013, has now become a huge name in 2D HTML5 games. Based on javascript, it can easily be integrated in a variety of javascript frameworks. 👾 👾 👾</p><p name="e7d1" class="graf graf--p graf-after--p">So why integrate Phaser and Ionic&nbsp;? 🚀 👾</p><p name="e0dc" class="graf graf--p graf-after--p">While Ionic gives you the power of creating apps and PWA at a lightening speed, you cannot really make games with it. Phaser, while great at game building, is not really about building a structured mobile or web-app. Hence, building a neat looking game app or PWA with Phaser requires an HTML + CSS wrapper, a void which Ionic perfectly fills.</p><figure tabindex="0" contenteditable="false" name="54e4" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 296px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 42.3%;"></div><img class="graf-image" data-image-id="1*YyudgL6_Ql09w7weTEW6-Q.gif" data-width="728" data-height="308" src="https://cdn-images-1.medium.com/max/720/1*YyudgL6_Ql09w7weTEW6-Q.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic and Phaser be like&nbsp;….</figcaption></figure><h3 name="0c82" class="graf graf--h3 graf-after--figure"><strong class="markup--strong markup--h3-strong">Step 1: Create an Ionic 4&nbsp;app</strong></h3><p name="8df4" class="graf graf--p graf-after--h3">First make sure you have latest Ionic installed</p><pre name="81c4" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">npm install -g ionic</code></pre><p name="ffd8" class="graf graf--p graf-after--pre">With Ionic CLI installed, create a simple Ionic app</p><pre name="9d5d" class="graf graf--pre graf-after--p">ionic start ioniser sidemenu</pre><p name="a9f0" class="graf graf--p graf-after--pre">I have picked <code class="markup--code markup--p-code">sidemenu</code> as a layout choice, but you can use <code class="markup--code markup--p-code">blank</code> or <code class="markup--code markup--p-code">tabs</code> as well. This command will generate a basic Ionic app with a <code class="markup--code markup--p-code">sidemenu</code> and some basic HTML in homepage. Serve your app using</p><pre name="9694" class="graf graf--pre graf-after--p">ionic serve</pre><p name="2c76" class="graf graf--p graf-after--pre">and check everything runs fine. For me it looks like following</p><figure tabindex="0" contenteditable="false" name="6d77" class="graf graf--figure graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 387px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 55.300000000000004%;"></div><img class="graf-image" data-image-id="1*H1h_3dUzlopbnG3vQULZrg.png" data-width="1388" data-height="768" src="https://cdn-images-1.medium.com/max/720/1*H1h_3dUzlopbnG3vQULZrg.png"><div class="crosshair u-ignoreBlock"></div></div></figure><h3 name="6026" class="graf graf--h3 graf-after--figure"><strong class="markup--strong markup--h3-strong">Step 2: Include Phaser in the&nbsp;project</strong></h3><p name="399b" class="graf graf--p graf-after--h3">Phaser is super-easy to include in the project. Essentially it is just a Javascript file that you need to include in your HTML5 project. There are two ways to do it</p><p name="06c2" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong"><em class="markup--em markup--p-em">#1&#8202;—&#8202;The cool “just-get-it-done” way (faster)</em></strong></p><p name="08aa" class="graf graf--p graf-after--p">Download <code class="markup--code markup--p-code"><em class="markup--em markup--p-em">phaser.min.js</em></code> from <a href="https://phaser.io/download/stable"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Phaser official downloads</a> and link it with your project. For demo purpose, I will keep this file in <code class="markup--code markup--p-code">assets</code> folder, but you can link it from CDN as well.</p><p name="8289" class="graf graf--p graf-after--p">Include the phaser.js file in <code class="markup--code markup--p-code">index.html</code> files as follows</p><pre name="232a" class="graf graf--pre graf-after--p">&lt;script src="assets/phaser.min.js"&gt;&lt;/script&gt;</pre><p name="8b35" class="graf graf--p graf-after--pre">Now you can include phaser in your component&nbsp;<code class="markup--code markup--p-code">.ts</code> files using</p><pre name="0fc6" class="graf graf--pre graf-after--p">declare var Phaser;</pre><p name="4457" class="graf graf--p graf-after--pre">(To check what <code class="markup--code markup--p-code">Phaser</code> contains, try consoling the variable or its <code class="markup--code markup--p-code">defaultState</code> saved in <code class="markup--code markup--p-code">this</code> and you’ll get some insights into Phaser’s built.)</p><p name="43fc" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong"><em class="markup--em markup--p-em">#2&#8202;—&#8202;The complex “I-am-a-coding-nerd” way</em></strong></p><p name="a764" class="graf graf--p graf-after--p">Download the npm package from phaser with</p><pre name="e6b9" class="graf graf--pre graf-after--p">npm install phaser-ce</pre><p name="12e6" class="graf graf--p graf-after--pre">Prepare <strong class="markup--strong markup--p-strong">webpack</strong> to compile the phaser package so you can <code class="markup--code markup--p-code">import</code> the package in the&nbsp;.ts file. You might have to prepare your own webpack-config for this and install additional modules. After this, you can import the variables as</p><pre name="9e68" class="graf graf--pre graf-after--p">import "pixi";<br>import "p2";<br>import * as Phaser from "phaser-ce";</pre><p name="d1c8" class="graf graf--p graf-after--pre">Details are given <a href="https://github.com/photonstorm/phaser-ce#browserify--cjs"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">here</a> (I am yet to try this method at the time of writing this blog)</p><h3 name="ccac" class="graf graf--h3 graf-after--p"><strong class="markup--strong markup--h3-strong">Step 3: Implement Phaser&nbsp;game</strong></h3><blockquote name="3c7b" class="graf graf--blockquote graf-after--h3"><strong class="markup--strong markup--blockquote-strong">You can find the complete code in the</strong><a href="https://store.enappd.com/product/ionic-phaser-game-framework-ionic-4/"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--blockquote-strong"> Ionic 4 Phaser Starter</strong></a></blockquote><p name="ad47" class="graf graf--p graf-after--blockquote">For sample purpose, we’ll use a simple <a href="https://phaser.io/examples/v2/animation/animation-events"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Phaser example</a> where we will make a <strong class="markup--strong markup--p-strong">Zombie</strong> walk.</p><figure tabindex="0" contenteditable="false" name="92ae" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 70.6%;"></div><div class="iframeContainer"><iframe data-width="435" data-height="307" width="435" height="307" src="/media/07fad9882eeb3c2e42bc9e9d96413a5d?postId=7fb1e917678e" data-media-id="07fad9882eeb3c2e42bc9e9d96413a5d" data-thumbnail="https://i.embed.ly/1/image?url=https://i.giphy.com/media/12AgpTvmc37CZG/giphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07" allowfullscreen="" frameborder="0"></iframe></div></div></figure><p name="5821" class="graf graf--p graf-after--figure">No, no, not that Zombie. 😆</p><p name="0005" class="graf graf--p graf-after--p">We will focus on <code class="markup--code markup--p-code">home</code> component that comes with the starter. So all the relevant javascript code will go in <code class="markup--code markup--p-code">home.page.ts</code> file. Replace the whole content in <code class="markup--code markup--p-code">home.page.html</code> file with the following</p><pre name="00a2" class="graf graf--pre graf-after--p">&lt;ion-content&gt;<br>  &lt;div id="phaser-example"&gt;&lt;/div&gt;<br>&lt;/ion-content&gt;</pre><p name="6e56" class="graf graf--p graf-after--pre">We will identify the <code class="markup--code markup--p-code">phaser-example</code> in our javascript logic and instantiate the game in this div.</p><p name="9469" class="graf graf--p graf-after--p">A basic Phaser game has three default functions&#8202;—&#8202;preload(), create() and update()</p><p name="cf30" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">&gt; Preload</strong>&#8202;—&#8202;As the name suggests, preloads assets etc. In our case, this function will load the zombie and background images.</p><pre name="d6b9" class="graf graf--pre graf-after--p">preload() {</pre><pre name="8b6f" class="graf graf--pre graf-after--pre">this.game.load.image('lazur', 'assets/thorn_lazur.png');</pre><pre name="5f39" class="graf graf--pre graf-after--pre">this.game.load.spritesheet('mummy', 'assets/metalslug_mummy37x45.png', 37, 45, 18);</pre><pre name="c011" class="graf graf--pre graf-after--pre">}</pre><p name="6e9d" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">&gt; Create</strong>&#8202;—&#8202;Creates the game instance and loads the game state. In our game, this function will set the images in the scene. We will also create and set animation listeners here.</p><pre name="72b0" class="graf graf--pre graf-after--p">create() {</pre><pre name="8d77" class="graf graf--pre graf-after--pre">// Set background</pre><pre name="cebd" class="graf graf--pre graf-after--pre">this.back = this.game.add.image(0, -400, 'lazur');</pre><pre name="f708" class="graf graf--pre graf-after--pre">this.back.scale.set(2);</pre><pre name="e121" class="graf graf--pre graf-after--pre">this.back.smoothed = false;</pre><pre name="c23e" class="graf graf--pre graf-after--pre">// Set mummy from a sprite</pre><pre name="a1e5" class="graf graf--pre graf-after--pre">this.mummy = this.game.add.sprite(200, 360, 'mummy', 5);</pre><pre name="7aa6" class="graf graf--pre graf-after--pre">this.mummy.scale.set(4);</pre><pre name="04b3" class="graf graf--pre graf-after--pre">this.mummy.smoothed = false;</pre><pre name="2c22" class="graf graf--pre graf-after--pre">// Set mummy animation</pre><pre name="b8a7" class="graf graf--pre graf-after--pre">this.anim = this.mummy.animations.add('walk');</pre><pre name="9e86" class="graf graf--pre graf-after--pre">this.anim.onStart.add(that.animationStarted, this);</pre><pre name="9f58" class="graf graf--pre graf-after--pre">this.anim.onLoop.add(that.animationLooped, this);</pre><pre name="c3a8" class="graf graf--pre graf-after--pre">this.anim.onComplete.add(that.animationStopped, this);</pre><pre name="a2a1" class="graf graf--pre graf-after--pre">this.anim.play(10, true);</pre><pre name="92a8" class="graf graf--pre graf-after--pre">}</pre><p name="93a2" class="graf graf--p graf-after--pre"><strong class="markup--strong markup--p-strong">&gt; Update</strong>&#8202;—&#8202;Update the game state on looping, actions, physics interactions etc. For our game, this will update the animation by moving the background to create the effect of a “walk”</p><pre name="26d7" class="graf graf--pre graf-after--p">update() {if (this.anim.isPlaying) { this.back.x -= 1;}}</pre><p name="3dcc" class="graf graf--p graf-after--pre">and Tada&nbsp;!!! 🎉 🎉🎉 We have our game running in the <em class="markup--em markup--p-em">serve </em>window</p><figure tabindex="0" contenteditable="false" name="16d7" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 600px; max-height: 333px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 55.50000000000001%;"></div><img class="graf-image" data-image-id="1*iTWUgMpxjmLFO9nXfnz31A.gif" data-width="600" data-height="333" src="https://cdn-images-1.medium.com/max/720/1*iTWUgMpxjmLFO9nXfnz31A.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Woohoo&nbsp;! It’s&nbsp;……&nbsp;alive</figcaption></figure><p name="6a1d" class="graf graf--p graf-after--figure">In the same way, you can run any Phaser game with Ionic. Trust me, there are some incredible looking <a href="https://phaser.io/examples"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">games made in Phaser</a>. We made a Mario replica some time back, which I will share in another blogpost.</p><p name="2686" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">⭐️️️️⭐️️️️⭐️️️️ Important️️ ⭐️️️️⭐️️️️⭐️️️️</strong></p><p name="2e04" class="graf graf--p graf-after--p">The Phaser implementation can leave you confused with the implementation of <code class="markup--code markup--p-code">this</code>&nbsp;. In short, once the Phaser scene is initialized, <code class="markup--code markup--p-code">this</code> contains the default game state. As an Ionic developer, or if you follow Ionic documentation, you will user <code class="markup--code markup--p-code">this</code> to refer to the component’s class. So you end up using conflicting <code class="markup--code markup--p-code">this</code>&nbsp;. For a quick work-around, I assign the Ionic<code class="markup--code markup--p-code">this</code> to another variable <code class="markup--code markup--p-code">that</code> (😅) and then use it to point to class functions.</p><p name="8a11" class="graf graf--p graf-after--p">A common mistake is to declare <code class="markup--code markup--p-code">that = this</code>&nbsp;. Yes, it does reference <code class="markup--code markup--p-code">this</code> via <code class="markup--code markup--p-code">that</code>&nbsp;, but as soon as <code class="markup--code markup--p-code">this</code> changes, <code class="markup--code markup--p-code">that</code> also changes, and hence there is no point of doing this. You might do <code class="markup--code markup--p-code">that = Object.assign({},this)</code> which is a good standard code. But you will find that this also does not result in what we want. Because in Ionic <code class="markup--code markup--p-code">this</code> contains the class functions inside <code class="markup--code markup--p-code">_prototype</code>&nbsp;, to copy those functions into <code class="markup--code markup--p-code">that</code> you should define it like</p><pre name="88ef" class="graf graf--pre graf-after--p">that = Object.create(this.constructor.prototype);</pre><p name="4af8" class="graf graf--p graf-after--pre">And then use <code class="markup--code markup--p-code">that</code> in place of <code class="markup--code markup--p-code">this</code> to call functions</p><p name="a2b0" class="graf graf--p graf-after--p">E.g. <code class="markup--code markup--p-code">that.animationStarted</code> points to a function <code class="markup--code markup--p-code">animationStarted</code>&nbsp;. Using <code class="markup--code markup--p-code">this</code> here would throw an error because <code class="markup--code markup--p-code">create()</code> function is a Phaser default and contains scene’s default state inside <code class="markup--code markup--p-code">this</code></p><p name="481e" class="graf graf--p graf-after--p">If you are not comfortable with the <code class="markup--code markup--p-code">this</code>concept, you should read more about it <a href="https://code.tutsplus.com/tutorials/fully-understanding-the-codethiscode-keyword--net-21117"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">here</a>.</p><p name="74a7" class="graf graf--p graf-after--p">(As another work-around, you can put the complete javascript code outside the class implementation of Ionic, or worse even, in a <code class="markup--code markup--p-code">&lt;script&gt;&lt;/script&gt;</code> tag in <code class="markup--code markup--p-code">index.html</code>&nbsp;, but that is too much of a hack. You won’t be able to write huge game codes this way)</p><h3 name="ce4c" class="graf graf--h3 graf-after--p"><strong class="markup--strong markup--h3-strong">Step 4: Build the game into a Progressive Web&nbsp;App</strong></h3><p name="a0a7" class="graf graf--p graf-after--h3">It is impressive to have the game running in your <code class="markup--code markup--p-code">ionic serve</code> window, but it would be a lot cooler if you can release this on your own domain. Ionic has your back.</p><p name="927a" class="graf graf--p graf-after--p">Prepare the app for a PWA deployment by running following commands</p><pre name="b697" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">ng add @angular/pwa</code></pre><p name="ce78" class="graf graf--p graf-after--pre">The <code class="markup--code markup--p-code">@angular/pwa</code> package will automatically add a service worker and a app manifest to the app. Then run</p><pre name="4482" class="graf graf--pre graf-after--p"><code class="markup--code markup--pre-code">ionic build --prod</code></pre><p name="ed58" class="graf graf--p graf-after--pre">to create a release build of the app. Now your app contains an <code class="markup--code markup--p-code">index.html</code> file which can be served over any server. The quickest way is to deploy on a firebase hosting by installing firebase-tools and deploying the game on your firebase project using <code class="markup--code markup--p-code">firebase deploy</code> (<a href="https://firebase.google.com/docs/hosting/deploying"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">details here</a>)</p><p name="5fbe" class="graf graf--p graf-after--p">🎉🎉🎉 Voila&nbsp;!! You own game is released on your website now🎉🎉🎉</p><h3 name="fe7c" class="graf graf--h3 graf-after--p"><strong class="markup--strong markup--h3-strong">Step 5&nbsp;: Build the game into a mobile&nbsp;app</strong></h3><p name="0fe1" class="graf graf--p graf-after--h3">Building an Ionic app with Phaser is exactly same as building a regular Ionic app. For those who are not familiar with the process in Ionic 4, first add the platform you want to run the app on</p><pre name="61fc" class="graf graf--pre graf-after--p">ionic cordova platform add android</pre><p name="2395" class="graf graf--p graf-after--pre">Then run the app on a connected device or an emulator by running</p><pre name="951e" class="graf graf--pre graf-after--p">ionic cordova run android</pre><p name="801d" class="graf graf--p graf-after--pre">You might want to adjust the <code class="markup--code markup--p-code">canvas</code> size as per the device size using <code class="markup--code markup--p-code">window.innerWidth</code> and <code class="markup--code markup--p-code">window.innerHeight</code>&nbsp;. With this, you can adjust the game canvas for all mobile devices sizes.</p><figure tabindex="0" contenteditable="false" name="46b8" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 375px; max-height: 666px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 177.6%;"></div><img class="graf-image" data-image-id="1*UVOdRt2TBBpR9YN1KWKqFQ.png" data-width="375" data-height="666" src="https://cdn-images-1.medium.com/max/720/1*UVOdRt2TBBpR9YN1KWKqFQ.png"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Got yourself a mobile&nbsp;game</figcaption></figure><p name="2bf2" class="graf graf--p graf-after--figure">With these tweaks, the game looks like above. Not bad, huh. 👻</p><p name="4da3" class="graf graf--p graf-after--p">Cool thing is, you can still have the <strong class="markup--strong markup--p-strong">sidemenu</strong>, or <strong class="markup--strong markup--p-strong">tabs</strong> like a mobile app and put in all regular functionalities of the app in the game (or vice versa) like login, signup etc. making use of Ionic plugins.</p><p name="b4d9" class="graf graf--p graf-after--p">Thinking of making your own PUBG or space invader game in Ionic&nbsp;?<a href="https://phaser.io/tutorials/coding-tips-007"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"> Try making this one</a></p><h3 name="79db" class="graf graf--h3 graf-after--p"><strong class="markup--strong markup--h3-strong">Conclusion</strong></h3><p name="142e" class="graf graf--p graf-after--h3">Ionic is super fast in making mobile apps, while Phaser is great for making 2D HTML5 games. Follow this blog to combine these two to make a quick mobile game app or game PWA. Make the game feature rich by using Ionic’s powerful plugins. Have fun&nbsp;!</p><blockquote name="ffbd" class="graf graf--blockquote graf-after--p">We do more such fun stuff at <strong class="markup--strong markup--blockquote-strong">Enappd</strong> on a regular basis. Feel free to browse through our <a href="http://enappd.com"  class="markup--anchor markup--blockquote-anchor" rel="noopener"    target="_blank">interesting app starters</a>.</blockquote><h3 name="e143" class="graf graf--h3 graf-after--blockquote">Update</h3><p name="a19d" class="graf graf--p graf-after--h3"><strong class="markup--strong markup--p-strong">Space-Invaders</strong> game now included in <code class="markup--code markup--p-code">space-invaders</code> branch on the same repo. This is how it looks like</p><figure tabindex="0" contenteditable="false" name="b1dc" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 521px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 74.5%;"></div><img class="graf-image" data-image-id="1*JGdK9H4TECzyH-EbWxKdtw.gif" data-width="796" data-height="593" src="https://cdn-images-1.medium.com/max/720/1*JGdK9H4TECzyH-EbWxKdtw.gif"><div class="crosshair u-ignoreBlock"></div></div><br/><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Space Invaders in Ionic +&nbsp;Phaser</figcaption></figure><h3 name="7ba6" class="graf graf--h3 graf-after--figure">FOUND THIS POST INTERESTING&nbsp;?</h3><p name="95a9" class="graf graf--p graf-after--h3">Also check out our other blog posts related to <a href="https://medium.com/enappd/how-to-use-firebase-with-ionic-4-complete-guide-for-beginners-1888b1034024"  class="markup--anchor markup--p-anchor"    target="_blank">Firebase in Ionic 4</a>, <a href="https://medium.com/enappd/using-geolocation-and-beacon-plugins-in-ionic-4-754b41304007"  class="markup--anchor markup--p-anchor"    target="_blank">Geolocation</a> in Ionic 4, <a href="https://medium.com/enappd/qr-code-scanning-and-optical-character-recognition-ocr-in-ionic-4-95fd46be91dd"  class="markup--anchor markup--p-anchor"    target="_blank">QR Code and scanners</a> in Ionic 4 and <a href="https://medium.com/enappd/payment-solutions-in-ionic-8c4bb28ce5cc"  class="markup--anchor markup--p-anchor"    target="_blank">Payment gateways in Ionic 4</a></p><h3 name="362a" class="graf graf--h3 graf-after--p">NEED FREE IONIC 4 STARTERS?</h3><p name="eff2" class="graf graf--p graf-after--h3">You can also find free Ionic 4 starters on our website <a href="http://enappd.com"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">enappd.com</a></p><ul class="postList"><li name="2b12" class="graf graf--li graf-after--p"><a href="https://store.enappd.com/product/free-chat-themes-ionic4/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Free Chat Themes Starter for Ionic 4</a></li><li name="a4be" class="graf graf--li graf-after--li"><a href="https://store.enappd.com/product/ionic4-firebase-starter/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Free Ionic 4&#8202;—&#8202;Firebase Starter</a></li></ul><p name="2930" class="graf graf--p graf-after--li">You can also make your next awesome app using <a href="https://store.enappd.com/product/ionic-4-full-app/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic 4 Full App</a></p><h3 name="1b1c" class="graf graf--h3 graf-after--p">References</h3><ul class="postList"><li name="bb4a" class="graf graf--li graf-after--h3 graf--trailing"><a href="https://ionicframework.com/docs"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Ionic documentation</a></li></ul></div></div></section></div></article></main>