I am using laravel shopify (previously maintained by osiset/gnikyt) package for almost 1 year now and Shopify is crazily changing the way apps are developed and introducing new changes quite frequently.

I have started my app using this package and BLADE template which worked fine and still works but there are so many issues coming due to the changes introduced by Shopify and you may have seen may issues related to the blade engine on the GitHub issues section of the package.

The recent change of the new admin URL of Shopify and the app bridge update again forced the package maintainer to make changes in the package and developers to update their apps according to new guidelines. I was thinking to update my app Easy Profile Editor to a SPA for a long time and I thought this is the right time to move to the SPA because Shopify has their official React Template for apps and most likely it’ll be up to date whenever they introduce any new change related to the app bridge and frontend.

Although now they also have an official PHP app template built on top of Laravel, because I am already using Laravel Shopify so I just wanted to use their React SPA with my current app. So let’s see how can you use laravel-shopify package with SPA.

Shopify app with laravel-shopify and React

I am not going to start from the beginning because setting up the package is easy and covered very well in the package documentation so we are going to focus mostly on React SPA part.


Set up React SPA in laravel-shopify app

Once the above steps are done, Follow the steps below

  • Clone or download this shopify-frontend-template-react repo in a separate folder.
  • create a folder named frontend in the resources folder of your Laravel app resources\frontend
  • Copy the folders shown in the image below from shopify-frontend-template-react to resources\frontend
  • Now compare shopify-frontend-template-react/package.json and shopify-laravel-app/package.json and move required dependencies and dev dependencies from the first package.json to the second package.json (My package.json file in shopify-laravel-app looks like this after this step)
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
"dependencies": {
"@shopify/app-bridge": "^3.1.0",
"@shopify/app-bridge-react": "^3.1.0",
"@shopify/app-bridge-utils": "^3.1.0",
"@shopify/polaris": "^9.11.0",
"@shopify/stylelint-polaris": "^5.1.0",
"@vitejs/plugin-react": "1.2.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-query": "^3.34.19",
"react-router-dom": "^6.3.0"
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.7.2",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"vite": "^4.0.0",
"history": "^5.3.0",
"jsdom": "^19.0.0",
"prettier": "^2.6.0",
"vi-fetch": "^0.6.1"
view raw package.json hosted with ❤ by GitHub
  • Update your .gitignore file if you want to ignore the dist folder to push on your version control remote repo, you can add /public/dist into the .gitignore file for this.
  • Run npm install into the shopify-laravel-app folder to install all the dependencies.
  • Now we have to modify our shopify-laravel-app/vite.config.js , the vite config provided by shopify-frontend-template-react has so many options and i had a hard time using it as it is with our laravel setup so i have modified it and created the vite.config.js as shown below which is working fine so you can just replace your shopify-laravel-app/vite.config.js with the code given below.
import { defineConfig, loadEnv } from "vite";
import laravel from "laravel-vite-plugin";
import react from "@vitejs/plugin-react";
import fs from "node:fs";
export default defineConfig(function ({ mode }) {
process.env = { …process.env, …loadEnv(mode, process.cwd()) }; //process.env is not accessible directly in this file so we have to do this
return {
plugins: [
laravel(["resources/css/app.css", "resources/js/app.js"]),
define: {
"process.env.SHOPIFY_API_KEY": JSON.stringify(
resolve: {
preserveSymlinks: true,
server: {
host: "localhost",
//below section is for SSL , if you are using self signed certificates for ssl on localhost you can map them here or remove this section
https: {
key: fs.readFileSync("../../etc/ssl/laragon.key"),
cert: fs.readFileSync("../../etc/ssl/laragon.crt"),
view raw vite.config.js hosted with ❤ by GitHub
  • Now we have to update .env file and add VITE_SHOPIFY_API_KEY=YOUR_KEY_HERE so vite.config.js can access Shopify API key in line 13. Also, add other environment variables that we need in our shopify-app.php config file.
view raw .env hosted with ❤ by GitHub
  • open shopify-laravel-app/resources/js/app.js and import our frontend’s entry file index.jsx into the app.js
import './bootstrap';
import "../css/app.css";
import '../frontend/index.jsx' //import react frontend entry file
view raw app.js hosted with ❤ by GitHub
  • Update the shopify-laravel-app/resources/views/welcome.balde.php with the code below so we can load our react app into this view
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Shopify Laravel Example</title>
<div id="app"></div>
  • Check your web.php file and make sure you have one get route names home and with verify.shopify middleware. Check the file below for reference.
use Illuminate\Support\Facades\Route;
| Web Routes
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
Route::view('/', 'welcome')->name('home')->middleware(['verify.shopify', 'billable']);
view raw web.php hosted with ❤ by GitHub
  • Lastly, run npm run dev from the root of your Laravel app folder and your Shopify app will be up and running with React SPA and laravel-shopify package.

Note that I am using billable middleware with SPA, to use the default billable middleware i have to modify vendor\kyon147\laravel-shopify\src\Http\Middleware\Billable.php file with the code below as per this comment so if you want to use billable middleware then make this change.

namespace Osiset\ShopifyApp\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Osiset\ShopifyApp\Contracts\Queries\Shop as ShopQuery;
use Osiset\ShopifyApp\Contracts\ShopModel as IShopModel;
use Osiset\ShopifyApp\Objects\Values\ShopDomain;
use Osiset\ShopifyApp\Util;
* Responsible for ensuring the shop is being billed.
class Billable
* The shop querier.
* @var ShopQuery
protected $shopQuery;
* @param ShopQuery $shopQuery The shop querier.
* @return void
public function __construct(ShopQuery $shopQuery)
$this->shopQuery = $shopQuery;
* Checks if a shop has paid for access.
* @param Request $request The request object.
* @param \Closure $next The next action.
* @return mixed
public function handle(Request $request, Closure $next)
if (Util::getShopifyConfig('billing_enabled') === true) {
/** @var $shop IShopModel */
$shop = $this->shopQuery->getByDomain(ShopDomain::fromNative($request->get('shop')));
if (! $shop->plan && ! $shop->isFreemium() && ! $shop->isGrandfathered()) {
// They're not grandfathered in, and there is no charge or charge was declined… redirect to billing
return Redirect::route(
array_merge($request->input(), ['shop' => $shop->getDomain()->toNative()])
// Move on, everything's fine
return $next($request);
view raw Billable.php hosted with ❤ by GitHub

Everything is working fine for me with this setup including HMR and the build is also working fine, I have not published my app yet after this BLADE to REACT migration so no idea about approval or rejection but don’t see any issues so I hope there will be no issues while approval.

The final code can be found here https://github.com/rvibit/laravel-shopify-react-spa


Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.