Shopify App With Laravel, InertiaJs, and Polaris
Shopify embedded apps are the best way to extend the existing functionality of Shopify to solve the merchant problems at scale, they have extensible platforms and APIs which can be used to build your app. You can also pull Shopify store data through their APIs into your app. this article is about how one can build the Shopify app with Laravel, InertiaJs, and Polaris.
Laravel
Laravel is a free, open-source PHP web framework, created by Taylor Otwell and intended for the development of web applications following the model–view–controller (MVC) architectural pattern and based on Symfony. Let’s start by creating a fresh copy of Laravel (if you are new to the Laravel check out their documentation for getting started).
composer create-project laravel/laravel laravel-shopify-app
This will create a laravel-shopify-app
directory, cd
the project directory as cd laravel-shopify-app
and serve the application as php artisan serve
, if you are using Laravel Valet
then run valet link
to serve your Laravel application if it's not already in the parked folder, make sure to secure the site with valet secure
also.
Laravel Breeze
We also have to install Laravel Breeze, it is a minimal, simple implementation of all of Laravel’s authentication features, including login, registration, password reset, email verification, and password confirmation but we are not going to use any of this authentication scaffolding, on the other hand, it also offers an Inertia.js frontend implementation powered by VueJS or ReactJS and exactly this is why we are using this package, let’s install this package.
composer require laravel/breeze --dev
This command will install Laravel Breeze as a dev dependency in our project, after this, we also have to install the InertiaJs implementation with React JS scaffolding.
php artisan breeze:install react
This command will publish all the assets including authentication views, routes, and controllers, you can delete all this which is not required, you can see the ReactJS component and other related stuff in the resources/js/
directory. After this run npm install
command to install all of the required npm packages and then run npm run dev
to build the npm assets.
Laravel Shopify Integration
Now it's time to start with Shopify integration, we are using osiset/laravel-shopify
it's a full-featured Laravel package for aiding in Shopify App development and it’ll work for Laravel 7 and up, run the below command to add it to the project.
composer require osiset/laravel-shopify
We also have to publish its configuration to our project,
php artisan vendor:publish --tag=shopify-config
This command creates a config file as shopify-app.php
in config
directory, we also need to provide the app_name
, api_key
, api_secret
, and api_scopes
to generate a working app.
Shopify App Configuration
Log in to your Shopify dev account, and then click on Apps
in the sidebar menu, go ahead and click on Create App
button at the top right side, you will be redirected to Create App
page.
In the create app page select Public App
and then fill in the form as,
- App Name: your Shopify app name
- App URL: https://<domain>,
e.g https://laravel-shopify-app.test
- Allowed redirection URL(s): https://<domain>/authenticate,
e.g https://laravel-shopify-app.test/authenticate
you can also use ngrok if you are not using the Laravel valet
Now, click on Create App
button at the top right corner, you will be redirected to the created app page, at the left side, you can see App keys
and secret
, copy and paste this App key and secret in Laravel’s .env
file as,
SHOPIFY_API_KEY=shopify-api-key-here
SHOPIFY_API_SECRET=shopify-api-secret-here
Now, open web.php
file and replace /
(root) route with the following.
Route::get('/', function () {
return view('welcome');
})->middleware(['verify.shopify'])->name('home');
After this open App\Models\User.php
(user model) and add the highlighted code to it.
<?phpnamespace App\Models;use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;use Osiset\ShopifyApp\Contracts\ShopModel as IShopModel;
use Osiset\ShopifyApp\Traits\ShopModel;class User extends Authenticatable implements IShopModel
{
use HasApiTokens, HasFactory, Notifiable, ShopModel; ..........
..........}
Make sure to configure the .env
file for the database and then run migrations as php artisan migrate
.
If you try to browse the app in the browser you’ll get the error
Call to a member function getDomain() on null
and that's ok.
Testing the App on Shopify
In the app details page in Shopify, click on More actions
and then select Test on development store
It’ll redirect you to a new page where you can select a previously created store or you can create a new one, while creating a new store just fill in the form and select development store and while choosing the previously created store click on a store to install the app in it, in next page you can click on Install unlisted app
it’ll install the app in the development store on then you can see the Laravel welcome page.
InertiaJS and ReactJS
Laravel integration to Shopify is done, now let's work on React part of our application, we already have a Welcome.js
page in the resources\js\pages
directory, let’s render this page from InertiaJs, open web.php
and make the changes as follows,
// Route::get('/', function () {
// return view('welcome');
// })->middleware(['verify.shopify'])->name('home');Route::get('/', function () {
return Inertia::render('Welcome');
})->middleware(['verify.shopify'])->name('home');
now open resources\js\pages\Welcome.js
file and replace it as follows
import React from 'react';
import { Link, Head } from '@inertiajs/inertia-react';export default function Welcome(props) {
return (
<>
<Head title="Welcome" />
<div className="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0">
<div className="max-w-6xl mx-auto sm:px-6 lg:px-8">
Welcome to shopify
</div>
</div>
</>
);
}
just refresh the Shopify app page and you can see the changes, ReactJs part of our page has been done.
Shopify Polaris
Shopify Polaris is a ReactJS component library designed to help developers create the best experience for merchants who use Shopify, we need to install the npm package for this also, run the below command in the Laravel project root.
npm install @shopify/polaris --save
Now, we have to import the Polaris CSS (comes with the Polaris package) in our project, open resources/js/app.js
make changes as follows
require('./bootstrap');import React from 'react';
import { render } from 'react-dom';
import { createInertiaApp } from '@inertiajs/inertia-react';
import { InertiaProgress } from '@inertiajs/progress';
import '@shopify/polaris/build/esm/styles.css';............
............
It’s time to see some Shopify Polaris components in action, open the Welcome.js, and update as follows, you can see all of the Polaris components here.
import React from 'react';
import enTranslations from '@shopify/polaris/locales/en.json';
import {Page, Card, Button, AppProvider} from '@shopify/polaris';const Welcome = ({ user }) => {
return (
<>
<AppProvider i18n={enTranslations}>
<Page title="Inertia App">
<Card title={ user.name } sectioned>
<Button
primary
onClick={() => {alert("I am here")} }
>
Click Me
</Button>
</Card>
</Page>
</AppProvider>
</>
);
}export default Welcome;
Make sure the npm run watch
is running, and then reload the Shopify app page, if everything works as expected you’ll see something like this,
We are using four components from Shopify Polaris as Page
, Card
, Button
, and AppProvider
, the AppProvider
is a required component that enables sharing global settings throughout the hierarchy of our application, note that the Polaris ReactJS components will not function without it.
We already know that the AppProvider component is a must in all our pages, so instead of adding it to all the pages again and again we can create a site layout that all of our pages can extend, we already have a Layouts folder in our application (thanks to Laravel Breeze), let's create a new Shopified.js
file in this folder and add the code as given below, it’ll be our site layout.
import React from 'react'
import '@shopify/polaris/build/esm/styles.css';
import enTranslations from '@shopify/polaris/locales/en.json';
import {AppProvider} from '@shopify/polaris';export default function Layout({ children }) {
return (
<main>
<AppProvider i18n={enTranslations}>
{children}
</AppProvider>
</main>
)
}
You can also remove
import ‘@shopify/polaris/build/esm/styles.css’;
line (we have added earlier) fromapp.js
file.
Now we have to update our Welcome.js
file to use our new site layout. let's make some updates to it:
import React from 'react';
import Shopified from "../Layouts/Shopified";
import {Page, Card, Button} from '@shopify/polaris';const Welcome = ({ user }) => {
return (
<>
<Page title="Inertia App">
<Card title={ user.name } sectioned>
<Button
primary
onClick={() => {alert("I am here")} }
>
Click Me
</Button>
</Card>
</Page>
</>
);
}Welcome.layout = page => <Shopified children={page} title="Welcome"/>
export default Welcome;
That’s it we have made it to the end, we used Laravel to build the Shopify app with ReactJs and Polaris Components but there is one more thing I want to add to this article, to understand it let's send a post request from the ReactJs page to the Laravel backend.
First, we have to create a post route in web.php
file to handle the post request, update the code as follows,
Route::middleware(['verify.shopify'])->group(function () {
Route::get('/', function () {
return Inertia::render('Welcome');
});
Route::post('/', function() {
dd("its working");
});
});
Now we have to make some changes in Welcome.js
file to send a post request to the Laravel, update it as follows
import React from 'react';
import Shopified from "../Layouts/Shopified";
import {Page, Card, Button} from '@shopify/polaris';
import { Inertia } from '@inertiajs/inertia';const Welcome = ({ user }) => { function handleSubmit(e) {
e.preventDefault()
Inertia.post('/')
} return (
<>
<Page title="Inertia App">
<Card title={ user.name } sectioned>
<Button
primary
onClick={handleSubmit}
>
Click Me
</Button>
</Card>
</Page>
</>
);
}Welcome.layout = page => <Shopified children={page} title="Welcome" />
export default Welcome;
I’ve added another function to handle the button click, in this function we are using the InertiaJs’s post method to send the post request, check if npm run watch
is running, if working then reload the page in Shopify and click on the Click Me
button, It’ll send the post request to the Laravel backend, but instead of a successful response, it’ll say that the page is expired, this is because of CSRF. We just have to make some changes to the project to make things work, Let’s dig into this.
Sending Post Request
Open the app.blade.php
file from resources/views
folder and make changes as follows
....
.......
<body class="font-sans antialiased">
@inertia @env ('local')
<script src="http://localhost:8080/js/bundle.js"></script>
@endenv @if( \Osiset\ShopifyApp\Util::getShopifyConfig('appbridge_enabled') )
<script src="https://unpkg.com/@shopify/app-bridge{{ \Osiset\ShopifyApp\Util::getShopifyConfig('appbridge_version') ? '@'.config('shopify-app.appbridge_version') : '' }}"></script> <script src="https://unpkg.com/@shopify/app-bridge-utils{{ \Osiset\ShopifyApp\Util::getShopifyConfig('appbridge_version') ? '@'.config('shopify-app.appbridge_version') : '' }}"></script>
<script
@if( \Osiset\ShopifyApp\Util::getShopifyConfig('turbo_enabled') )
data-turbolinks-eval="false"
@endif
> var AppBridge = window['app-bridge'];
var actions = AppBridge.actions;
var utils = window['app-bridge-utils'];
var createApp = AppBridge.default;
var app = createApp({ apiKey: "{{ \Osiset\ShopifyApp\Util::getShopifyConfig('api_key', $shopDomain ??Auth::user()->name ) }}", shopOrigin: "{{ $shopDomain ?? Auth::user()->name }}",
host: "{{ \Request::get('host') }}",
forceRedirect: true,
});
</script> @include('shopify-app::partials.token_handler')
@include('shopify-app::partials.flash_messages')
@endif</body>
....
......
Now we have to do one more thing, open session.php
from config folder and find SESSION_SECURE_COOKIE
and replace the whole line as
.....
.......‘secure’ => env(‘SESSION_SECURE_COOKIE’, true),.......
.....
Now reload the Shopify page and send the request again by clicking on the button and magic!!! it’s working, yes we are done here for now but it’s the beginning, not the end.
Github Repository
Conclusion
Shopify is the leading platform for e-commerce and it has an extensible platform, APIs, and developer tools that help you design apps that solve merchant problems at scale, on other hand, Laravel is a very good framework to build flexible and scalable applications, with the help of InertiaJs framework with Laravel we can build modern single page application with ReactJs, Vuejs, and Svelte, hence in this article we have used these three technologies together to build a demo app for Shopify.