This guide turns the LaraClassifier Mobile App or the JobClass Mobile App into your own app, connected to your LaraClassifier or JobClass website, and publishes it on Google Play and the App Store. Both apps follow exactly the same steps; the few differences between them are pointed out along the way.
You don't need to know React Native. You edit two settings files, replace the icon and run a few commands. The apps are built in the cloud by Expo (EAS Build), so you need neither a Mac to build the iOS app nor Android Studio.
brand.json), unless stated otherwise. On Windows, use PowerShell or Windows Terminal.
Checklist
| You need | Where to get it |
|---|---|
| LaraClassifier or JobClass 19.1.13 or later, on HTTPS | Your website. |
The API token of your website (APP_API_TOKEN) | The /.env file of your website. |
| Node.js 22.13 or later | nodejs.org |
| An Expo account (free) | expo.dev/signup |
| A Google Play Console account | play.google.com/console |
| An Apple Developer Program membership | developer.apple.com/programs |
| Your app icon (1024 × 1024 PNG), screenshots, privacy policy URL | You. |
| Test accounts on your website, for your own tests and for the store reviewers | Your website. JobClass: one job seeker (with a resume) and one employer (with a company and a job ad). |
1. Prepare Your Website
- Update your website to LaraClassifier or JobClass 19.1.13 or later.
- Check HTTPS: your website must open with
https://and a valid certificate (not self-signed). Published apps refuse plain HTTP. - Get the API token: open the
/.envfile at the root of your website and copy the value ofAPP_API_TOKEN. If the line is missing or empty, add a long random value, for example:
then clear the configuration cache from Admin panel → Clear cache (or runAPP_API_TOKEN=replace-with-a-long-random-valuephp artisan config:clear). - Test the API from your computer, with your own address and token:
You should get a JSON answer that starts withcurl -H "X-AppApiToken: YOUR_TOKEN" -H "Accept: application/json" https://www.your-website.com/api/categories{"success":true. - Check
FALLBACK_LOCALE_FOR_DBin/.env: it must be the language of your categories and cities data (usuallyen), otherwise users of other languages see empty lists. - JobClass only: check the job types and salary types of your admin panel. The posting form requires a job type and a pay period, so at least one active entry of each is needed.
2. Install the Project
- Unzip the package you downloaded and open a terminal in the app folder.
- Install the dependencies:
npm install
3. Connect the App to Your Website
Copy .env.example to a new file named .env.local (in the same folder) and fill it in:
EXPO_PUBLIC_API_URL=https://www.your-website.com/api
EXPO_PUBLIC_API_TOKEN=your-app-api-token
EXPO_PUBLIC_DEFAULT_COUNTRY=US
EXPO_PUBLIC_LOCALE=en
| Setting | Value |
|---|---|
EXPO_PUBLIC_API_URL | Your website address followed by /api, without a trailing slash. Use the exact address of your website, with or without www, as it opens in a browser. |
EXPO_PUBLIC_API_TOKEN | The APP_API_TOKEN of your website. |
EXPO_PUBLIC_DEFAULT_COUNTRY | Country shown on first launch (2-letter code). Users can change it. |
EXPO_PUBLIC_LOCALE | Language used when the phone's language is not available in the app. |
npx expo start --clear, and rebuild the app for the stores.
4. Rebrand the App
brand.json
Open brand.json and replace the example values. Here is the LaraClassifier version:
{
"name": "My Classifieds",
"slug": "my-classifieds",
"scheme": "myclassifieds",
"version": "1.0.0",
"ios": { "bundleIdentifier": "com.mycompany.classifieds", "buildNumber": "1" },
"android": { "package": "com.mycompany.classifieds", "versionCode": 1 },
"colors": {
"primary": "#141B3D",
"accent": "#2F54EB",
"priceTag": "#FFD23F",
"splashBackground": "#141B3D",
"dark": { "primary": "#F1F3FB", "accent": "#8099FF" }
},
"assets": { ... },
"social": { ... },
"eas": { "projectId": "", "owner": "" }
}
The JobClass file is the same, with job board examples ("My Jobs", com.mycompany.jobs) and salaryTag instead of priceTag.
| Field | Description |
|---|---|
name | The app name under the icon. Keep it short: about 12 characters are visible on most phones. |
slug | Technical name of the project on Expo. Lowercase letters, digits and dashes. |
scheme | Link scheme of the app (for example myclassifieds:// or myjobs://). Lowercase letters only, unique to your app. |
version | Version shown in the stores, for example 1.0.0. |
ios.bundleIdentifierandroid.package | The unique identifier of your app in the stores, in reverse domain format: com.yourcompany.yourapp. It can never be changed after the first publication. Don't keep the example value (com.example.classifieds or com.example.jobs). |
ios.buildNumberandroid.versionCode | Build number, increased at each upload to the stores (see "Publishing updates" below). |
colors.primary | Buttons, selected filters and the central tab button (Sell on LaraClassifier, Post a job on JobClass). |
colors.accent | Links, active states and counters. |
colors.priceTag (LaraClassifier)colors.salaryTag (JobClass) | The price sticker on listings, or the salary sticker on job ads. The color of the text placed on top of your colors is chosen automatically for readability. |
colors.splashBackground | Background of the launch screen. |
colors.dark | Primary and accent colors in dark mode. Pick light tones, which stay readable on the dark background. |
assets | Paths of the icon, adaptive icon, launch image and favicon (see below), and the background color of the Android adaptive icon. |
social | Google and Facebook sign-in IDs. Leave them empty to hide these buttons (see the push notifications, social sign-in and app links article). |
eas.projectId, eas.owner | Filled in at step 6. |
Icon and launch screen
Replace the placeholder images in assets/brand/, keeping the file names (or update the paths in brand.json):
| File | Size | Content |
|---|---|---|
icon.png | 1024 × 1024 | The app icon (iOS and default). Square, no transparency, no rounded corners: the phone rounds them. |
adaptive-icon.png | 1024 × 1024 | Foreground of the Android icon, on a transparent background. Keep the logo inside the central 66% circle: Android crops the edges. |
splash.png | 512 × 512 or more | Logo shown on the launch screen, on a transparent background, over colors.splashBackground. |
favicon.png | 64 × 64 | Icon of the web version (optional). |
5. Test on Your Phone
- Install Expo Go from the App Store or Google Play and sign in with your Expo account.
- On your computer, sign in to the same account and start the app:
npx expo login npx expo start - Scan the QR code shown in the terminal (with the Camera app on iPhone, or from Expo Go on Android). Your phone and your computer must be on the same network.
- Check the main screens:
- LaraClassifier: the home page, a search and a listing; sign in with a test account and post a test listing with a photo.
- JobClass: the home page, a search and a job ad; sign in with your test job seeker account and apply with a resume; then sign in with your test employer account, post a test job ad with a company logo, open the application in Messages and change its status.
If your website runs on your computer and is not online yet, follow the steps below first.
Testing with a website on your computer
Your phone can't open localhost or local domains such as my-site.test or my-site.local (the virtual hosts of MAMP, Laragon, Valet, etc.): they only exist on your computer. The phone reaches your computer through its IP address on your Wi-Fi network, so the website must answer on that address.
- Connect your phone and your computer to the same Wi-Fi network. Avoid guest networks: they usually stop devices from reaching each other.
- Find the IP address of your computer on the network:
The examples below useSystem Command macOS ipconfig getifaddr en0(or System Settings → Wi-Fi → Details)Windows ipconfig, then read the IPv4 Address of your Wi-Fi adapterLinux hostname -I(the first address)192.168.1.20and the port8000: replace them with yours. - In a terminal opened in the website folder, clear the cached configuration:
php artisan config:clear - Start the website so the network can reach it, with
APP_URLset to the address the phone will use (the website builds the addresses of photos, logos, pages and resume links from it). Pick one of these two ways:- With
php artisan serve: in the website's/.envfile, setAPP_URL=http://192.168.1.20:8000(note the previous value, to put it back after testing), runphp artisan config:clearagain, then start the server:php artisan serve --host=0.0.0.0 --port=8000 - With PHP's built-in server, without editing
/.env: go to the website'spublicfolder and passAPP_URLto the server only:
On Windows (PowerShell), set the variable first:cd public APP_URL=http://192.168.1.20:8000 php -S 0.0.0.0:8000 ../vendor/laravel/framework/src/Illuminate/Foundation/resources/server.phpcd public $env:APP_URL="http://192.168.1.20:8000" php -S 0.0.0.0:8000 ../vendor/laravel/framework/src/Illuminate/Foundation/resources/server.php
- With
- Check the connection: open
http://192.168.1.20:8000/api/categoriesin the phone's browser. A short JSON message (even "You don't have access to this API") means the phone reaches your website. If the page doesn't load, see the troubleshooting article. - In the app's
.env.local, use the same address followed by/api:EXPO_PUBLIC_API_URL=http://192.168.1.20:8000/api - In a second terminal, opened in the app folder, start the app on your network and scan the QR code to open it in Expo Go:
On iPhone, accept when Expo Go asks to find devices on your local network.npx expo start --lan --clear
/.env has IMAGE_DRIVER=imagick and the command-line PHP has no Imagick extension, the website accepts no image format. While testing, set IMAGE_DRIVER=gd in the website's /.env (or install Imagick for the command-line PHP), run php artisan config:clear, then restart the server.
APP_URL and EXPO_PUBLIC_API_URL. Servers that pick the website by its domain name (virtual hosts) often don't answer on the IP address, which the two methods above avoid.
http addresses. When you're done testing, stop the server (Ctrl+C), put back the original APP_URL of the website if you changed it, and set EXPO_PUBLIC_API_URL to your online HTTPS website before building the app for the stores.
6. Set Up Expo Builds
- Install the EAS command-line tool and sign in:
npm install --global eas-cli eas login - Create the project on Expo:
eas initeas initprints a project ID. Copy it intobrand.json, with your Expo account name (or organization) as owner:
If"eas": { "projectId": "1a2b3c4d-...", "owner": "your-expo-account" }eas initoffers to edit the app configuration automatically, answer no: the configuration is generated frombrand.json.
The build profiles are already defined in eas.json: preview builds an Android APK to install directly on phones, production builds the files for the stores.
7. Build a Test Version
Build an Android APK that you and your testers install directly, without going through the stores:
eas build --platform android --profile preview
When the build is done (10 to 20 minutes), EAS shows a link and a QR code to download the APK. For iOS test builds, use TestFlight (see step 9). Test builds also receive push notifications and support social sign-in, which Expo Go on Android doesn't.
8. Publish on Google Play
- Build the Android App Bundle:
On the first build, EAS creates and keeps the signing key of your app: answer yes when it offers to generate a keystore.eas build --platform android --profile production - In the Google Play Console, create the app (name, default language, app, free).
- Complete the App content section: privacy policy URL (the privacy page of your website), ads, app access (give your test accounts: reviewers need to sign in), content rating questionnaire, target audience, and data safety (see the store review tips below). For JobClass, choose the Business category.
- Complete the Store listing: short and full description, icon (512 × 512), feature graphic (1024 × 500) and phone screenshots.
- Upload the build: download the
.aabfile from the EAS build page and upload it in Testing → Internal testing (recommended first), then promote it to Production. Once the first version has been uploaded by hand and a Google service account key is configured, you can also upload witheas submit --platform android(Expo guide).
9. Publish on the App Store
- In App Store Connect, create the app with the same bundle identifier as
ios.bundleIdentifierinbrand.json. - Build the iOS app:
EAS asks for your Apple account and creates the certificates and provisioning profile for you.eas build --platform ios --profile production - Upload the build to App Store Connect:
eas submit --platform ios - After Apple has processed it, the build appears in TestFlight. Install it on your iPhone with the TestFlight app and test it.
- Complete the app page: description, keywords, primary category (Business for JobClass), support URL, privacy policy URL, screenshots (6.9" and 6.5" iPhone, 13" iPad), App Privacy answers, age rating, and in App Review Information your test accounts (email and password) with a note explaining that the app is the companion of your website.
- Select the build and submit it for review.
Store Review Tips
- Test accounts: give reviewers a working account with a few listings and messages (LaraClassifier), or two accounts so they see both sides of the app (JobClass): a job seeker with a resume, and an employer with a company, job ads and applications. Reviews without a working sign-in are rejected.
- Content on your website: reviewers look at your listings or job ads. Remove test and placeholder content (lorem ipsum, fake prices, fake companies, fake salaries) before submitting.
- User-generated content: Apple and Google require terms of use accepted by the users, a way to report objectionable content, a way to block abusive users, and a way for you to act on reports. The app has all of them: terms acceptance at sign-up, Report on each listing or job ad, Block on listings or job ads and on conversations, and your admin panel to remove content and ban users. Make sure your website has a page of type Terms and one of type Privacy (Admin panel → Pages), and mention these features in the review notes.
- Account deletion: required by both stores, available in Account → Delete my account.
- Privacy answers (App Privacy / Data safety): the app sends to your website the data the user enters to provide the service (name, email, phone, photos, listings and messages; on JobClass also company details and logos, resumes and cover letters). It contains no third-party analytics or advertising SDK. As the operator of the website, you are responsible for the answers.
- Paid promotion on iOS: Promote is only shown on Android. Apple requires its own in-app purchase system for digital services sold in iOS apps, so the iOS app has no payment and no link to one. Don't mention premium plans or paid listings / job ads in your App Store description, screenshots or review notes: iOS users buy them on the website.
- Name and icon: they must be yours. Don't use the names or logos of other brands.
Store listing
- Say what users get in the first lines: buy and sell near them (LaraClassifier), or search jobs near them, apply with their resume in a few taps and follow their applications, and for employers, post job ads and answer candidates on the go (JobClass).
- Show the screens that sell the app: the home page with featured content, a search with filters, a listing or job ad page, and (for JobClass) the apply form with a resume and the application status in Messages.
- Use the keywords people search for (classifieds or jobs, your city or country, your niche or industry) and the name of your website.
- Show your own brand and real content from your website in the screenshots, not the example name of the app.
Publishing Updates
To publish a new version of your app (a new version of the product, a new icon, new colors):
- Increase the numbers in
brand.json:version(for example1.0.1),ios.buildNumber(for example"2") andandroid.versionCode(for example2). The stores refuse a build number they have already received. - Build and submit again (steps 8 and 9).
Changes made on your website (categories, job types, settings, languages, content) don't require an app update.
Updating to a new version of the product
- Keep a copy of your
brand.json,.env.localandassets/brand/, and of any file you modified. - Replace the other files with the new version, then copy your files back.
- Run
npm install, read the ChangeLog shipped in thedocs/folder of the download (some versions require a newer LaraClassifier or JobClass), test, and publish.
Going Further
- Mobile App: Push Notifications, Social Sign-In and App Links: the extra setup for push notifications, Google and Facebook sign-in, and links that open in the app.
- Mobile App Troubleshooting: what to check when the app can't connect, uploads fail or a build doesn't work.
- The features of each app: LaraClassifier Mobile App: User Guide and JobClass Mobile App: User Guide.