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.

Where to type the commands: in a terminal opened in the app folder (the folder that contains brand.json), unless stated otherwise. On Windows, use PowerShell or Windows Terminal.

Checklist

You needWhere to get it
LaraClassifier or JobClass 19.1.13 or later, on HTTPSYour website.
The API token of your website (APP_API_TOKEN)The /.env file of your website.
Node.js 22.13 or laternodejs.org
An Expo account (free)expo.dev/signup
A Google Play Console accountplay.google.com/console
An Apple Developer Program membershipdeveloper.apple.com/programs
Your app icon (1024 × 1024 PNG), screenshots, privacy policy URLYou.
Test accounts on your website, for your own tests and for the store reviewersYour website. JobClass: one job seeker (with a resume) and one employer (with a company and a job ad).

1. Prepare Your Website

  1. Update your website to LaraClassifier or JobClass 19.1.13 or later.
  2. Check HTTPS: your website must open with https:// and a valid certificate (not self-signed). Published apps refuse plain HTTP.
  3. Get the API token: open the /.env file at the root of your website and copy the value of APP_API_TOKEN. If the line is missing or empty, add a long random value, for example:
    APP_API_TOKEN=replace-with-a-long-random-value
    then clear the configuration cache from Admin panel → Clear cache (or run php artisan config:clear).
  4. Test the API from your computer, with your own address and token:
    curl -H "X-AppApiToken: YOUR_TOKEN" -H "Accept: application/json" https://www.your-website.com/api/categories
    You should get a JSON answer that starts with {"success":true.
  5. Check FALLBACK_LOCALE_FOR_DB in /.env: it must be the language of your categories and cities data (usually en), otherwise users of other languages see empty lists.
  6. 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.
Keep the token private. It is compiled into the app, so a determined user could find it, but don't publish it on websites or in public repositories. Everything private also requires the user to be signed in, and on JobClass, resumes are only reachable through temporary signed links.

2. Install the Project

  1. Unzip the package you downloaded and open a terminal in the app folder.
  2. 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
SettingValue
EXPO_PUBLIC_API_URLYour 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_TOKENThe APP_API_TOKEN of your website.
EXPO_PUBLIC_DEFAULT_COUNTRYCountry shown on first launch (2-letter code). Users can change it.
EXPO_PUBLIC_LOCALELanguage used when the phone's language is not available in the app.
Tip: these values are compiled into the app. After changing them, restart with 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.

FieldDescription
nameThe app name under the icon. Keep it short: about 12 characters are visible on most phones.
slugTechnical name of the project on Expo. Lowercase letters, digits and dashes.
schemeLink scheme of the app (for example myclassifieds:// or myjobs://). Lowercase letters only, unique to your app.
versionVersion shown in the stores, for example 1.0.0.
ios.bundleIdentifier
android.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.buildNumber
android.versionCode
Build number, increased at each upload to the stores (see "Publishing updates" below).
colors.primaryButtons, selected filters and the central tab button (Sell on LaraClassifier, Post a job on JobClass).
colors.accentLinks, 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.splashBackgroundBackground of the launch screen.
colors.darkPrimary and accent colors in dark mode. Pick light tones, which stay readable on the dark background.
assetsPaths of the icon, adaptive icon, launch image and favicon (see below), and the background color of the Android adaptive icon.
socialGoogle 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.ownerFilled 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):

FileSizeContent
icon.png1024 × 1024The app icon (iOS and default). Square, no transparency, no rounded corners: the phone rounds them.
adaptive-icon.png1024 × 1024Foreground of the Android icon, on a transparent background. Keep the logo inside the central 66% circle: Android crops the edges.
splash.png512 × 512 or moreLogo shown on the launch screen, on a transparent background, over colors.splashBackground.
favicon.png64 × 64Icon of the web version (optional).

5. Test on Your Phone

  1. Install Expo Go from the App Store or Google Play and sign in with your Expo account.
  2. On your computer, sign in to the same account and start the app:
    npx expo login
    npx expo start
  3. 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.
  4. 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.

  1. Connect your phone and your computer to the same Wi-Fi network. Avoid guest networks: they usually stop devices from reaching each other.
  2. Find the IP address of your computer on the network:
    SystemCommand
    macOSipconfig getifaddr en0 (or System Settings → Wi-Fi → Details)
    Windowsipconfig, then read the IPv4 Address of your Wi-Fi adapter
    Linuxhostname -I (the first address)
    The examples below use 192.168.1.20 and the port 8000: replace them with yours.
  3. In a terminal opened in the website folder, clear the cached configuration:
    php artisan config:clear
  4. Start the website so the network can reach it, with APP_URL set 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 /.env file, set APP_URL=http://192.168.1.20:8000 (note the previous value, to put it back after testing), run php artisan config:clear again, 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's public folder and pass APP_URL to the server only:
      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.php
      On Windows (PowerShell), set the variable first:
      cd 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
    Keep this terminal open while you test. If the firewall of your computer asks whether PHP may accept incoming connections, allow it.
  5. Check the connection: open http://192.168.1.20:8000/api/categories in 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.
  6. In the app's .env.local, use the same address followed by /api:
    EXPO_PUBLIC_API_URL=http://192.168.1.20:8000/api
  7. 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:
    npx expo start --lan --clear
    On iPhone, accept when Expo Go asks to find devices on your local network.
Image uploads refused with "must be a file of type: ."? Both servers above run the command-line PHP of your computer, which can differ from the PHP of your usual local server. When the website's /.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.
Already using a local server (MAMP, XAMPP, Laragon, Valet, etc.)? It works too when it accepts connections from the network: use its IP address and port in 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.
Plain HTTP is fine for testing in Expo Go, but store builds refuse plain 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

  1. Install the EAS command-line tool and sign in:
    npm install --global eas-cli
    eas login
  2. Create the project on Expo:
    eas init
    eas init prints a project ID. Copy it into brand.json, with your Expo account name (or organization) as owner:
    "eas": { "projectId": "1a2b3c4d-...", "owner": "your-expo-account" }
    If eas init offers to edit the app configuration automatically, answer no: the configuration is generated from brand.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

  1. Build the Android App Bundle:
    eas build --platform android --profile production
    On the first build, EAS creates and keeps the signing key of your app: answer yes when it offers to generate a keystore.
  2. In the Google Play Console, create the app (name, default language, app, free).
  3. 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.
  4. Complete the Store listing: short and full description, icon (512 × 512), feature graphic (1024 × 500) and phone screenshots.
  5. Upload the build: download the .aab file 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 with eas submit --platform android (Expo guide).
New personal Play Console accounts must run a closed test with testers for a while before they can publish to production. Check the current requirement in your Play Console.

9. Publish on the App Store

  1. In App Store Connect, create the app with the same bundle identifier as ios.bundleIdentifier in brand.json.
  2. Build the iOS app:
    eas build --platform ios --profile production
    EAS asks for your Apple account and creates the certificates and provisioning profile for you.
  3. Upload the build to App Store Connect:
    eas submit --platform ios
  4. After Apple has processed it, the build appears in TestFlight. Install it on your iPhone with the TestFlight app and test it.
  5. 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.
  6. 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):

  1. Increase the numbers in brand.json: version (for example 1.0.1), ios.buildNumber (for example "2") and android.versionCode (for example 2). The stores refuse a build number they have already received.
  2. 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

  1. Keep a copy of your brand.json, .env.local and assets/brand/, and of any file you modified.
  2. Replace the other files with the new version, then copy your files back.
  3. Run npm install, read the ChangeLog shipped in the docs/ folder of the download (some versions require a newer LaraClassifier or JobClass), test, and publish.

Going Further

Was this article helpful?

Thank you for your feedback!

Still need help? Create a support ticket

Create a Ticket