Skip to content

A mobile app for your online store, from the same Laravel admin ​

A store that sells well on the web gets asked for an app sooner or later. Customers want it on the home screen, they want to be told when the parcel ships, and the owner wants a second shop window that nobody has to find in a browser. Then the quotes come in. An agency builds one from scratch for the price of a car, and it has its own backend to keep in step with the shop. The app builders re-skin a template for a monthly fee, and every rule the shop has — a coupon that applies to one category, free delivery from sixty dollars, a product you can only buy on the site — has to be made twice or dropped.

The shop already knows all of that. Its pages know what is in stock and at what price, its cart knows the coupons and the shipping zones, its checkout knows which fields it needs and which payment methods it offers. An app should ask the shop and draw the answer, not know it again.

That is what the kitloom app does, and since 1.17.0 kitloom/mobile-apps is the site's side of it.

One app, your store ​

The app is one Expo (React Native) project, kitloom/app, for every kitloom store. A single file, kitloom.json, names the site: its address, its name, colours, the icon and the splash, the bundle id. npm run configure -- https://your-store.example fills it from the site itself, and eas build makes the iPhone and Android builds in Expo's cloud under your own Apple Developer and Google Play accounts, so the app in the stores is yours, under your name, with your icon. No Xcode on anyone's desk.

What the customer gets on the phone:

  • Home: the shop's banners, the categories, shelves of what is on sale, new and popular — the same records the site's front page shows.
  • Shop: search, categories, sorting, and the attribute filters of the catalogue — the style of a beer, its strength, the format — the same filters as on the site's archive, read from the same page.
  • A product: its gallery with pictures to pinch and zoom, the variations, the reviews, the related products, a quantity and Add to cart.
  • The cart: kept on the phone, swipe a line away, a coupon, the shipping rates for the address, and the totals the site worked out.
  • Checkout in three steps: address, delivery, payment. A signed-in customer is not asked what the site already knows; a shop that delivers in one city asks only for the street. Cash on delivery and a bank transfer end in the app; a card gateway opens in the browser and the app reads the order back.
  • The account: the orders with their status, the addresses, the downloads, and — once kitloom/bookings is installed — the appointments. The app names no module: a section another module adds to the site's account page is on the phone at once.
  • Push: Your order #1042 is on its way when the owner marks it shipped, in the site's language.

The catalogue needs nothing new on the site. Every page of a kitloom site answers as JSON when asked for it, exactly what the site's own Vue, React or Blade theme draws, so a product, a category, a search and the front page are read from their own addresses. The module adds what a phone needs beyond the pages.

The site's side ​

The admin gets a Mobile app section with two screens.

Settings has the main switch, Serve the app: until it is on, the app's addresses answer not found and no phone is told anything. Under it, the install links — the App Store and Google Play links once the app is listed, a public TestFlight link and an APK while it is being tried; the site's theme shows them, the app shows them to nobody. The App Store id, with the banner switched on, makes Safari on an iPhone offer the app at the top of every page of the site: one meta tag, no script, no cookie. Push about orders tells the customer's phone when the order is placed and whenever its status changes, through Expo's push service, which holds the app's Apple and Google credentials; an access token from Expo's dashboard is optional and kept encrypted. Oldest app version served tells an old build to update before it goes on. And downloadable products stay off by default: Apple makes an app sell digital goods through its own purchases, so a download is bought on the site, while physical goods and services are paid as on the site.

Devices lists the phones the app runs on — the name the phone gives itself, iOS or Android, whose it is or A guest, the app's version, when it was last seen. Delete one and it hears nothing more; the app on it keeps working, and a sign-in registers it again.

A sign-in from the app is a sign-in to the site: the same email or login name and password, the same locks against guessing. It mints an application password named after the phone — "Ada's iPhone · Green Pantry" — which the phone keeps as its token and which is listed with the user's other application passwords, on their profile and under REST API, where revoking it signs the phone out. An account protected by a second factor is asked to use the site.

The App Store requires that an app which makes accounts lets the user delete theirs from the app. With kitloom/privacy installed the app files an erasure request for the user's own email, the person confirms it from the email, and the owner erases what the law lets go under Tools → Erase Personal Data, where the devices are exported and erased with the rest.

A store you can try on your phone ​

We run one as the stand: Prairie Hops, a craft beer shop in Winnipeg, at pantry.kitloom.dev. Twenty-three beers in eight categories, filters by style, strength, format and brewery, delivery in the city for six dollars and free from sixty, pickup at the taproom. Its Android build goes to testers by link and TestFlight follows; the site's Mobile app → Settings is where the store links go the day they are public.

For a Laravel developer ​

The module mounts app/v1 under the site's REST root, with WordPress's JSON errors. GET /site answers the site's facts in one request: name, icon, currency, the shop's pages, the payment methods, the account's sections, the install links, the minimum version. POST /auth/sign-in runs the login form's own checks — Kitloom\Site\Auth\PasswordCheck, extracted from the login controller in this release so a form and an app refuse a password the same way — and answers a Sanctum token from kitloom/api's application passwords. POST /cart/quote prices the phone's lines with the shop's own Cart, so a coupon or a shipping zone is never written twice, and says per line what cannot be bought. POST /checkout is Checkout::placeOrder() with the same fields and checks as the site's form. GET /account/{section} reads whatever is tagged AccountSection::TAG. Push is a queued job per phone through Expo's API, and an hourly command reads the receipts and forgets the phones Apple and Google no longer know.

Octane-safe, every option written through SettingWriter with the acting user, the Expo token encrypted and never read back by the form, tests in the package. The app's code is TypeScript on Expo Router, TanStack Query and Zustand, with a test run of its own.

Watch it ​

Mobile app: your store on the phone
Mobile app: the phones it runs on

Try it ​

Open a sandbox in one click, with no sign-up: Filament or Nova. Every route and option of the module is in the Mobile app guide.

Last updated:

kitloom — modules and themes for Laravel.
Contact · Pricing · Services · License · Refunds · Privacy · Community · YouTube · [email protected]