DEV Community

Anikesh Kumar
Anikesh Kumar

Posted on

How to Build a Native Mobile App with Next.js

Developing native mobile applications can be time-consuming and complex. However, by leveraging the power of Next.js and BagistoNative, you can streamline this process, making it faster and easier than ever before.

BagistoNative allows you to seamlessly convert your existing Next.js project into real native mobile apps for iOS and Android. This way, you can maintain a single codebase while ensuring your app works across web, iOS, and Android platforms.

In this guide, we’ll walk you through the entire process of setting up a mobile app using Next.js and BagistoNative, so you can get started quickly and efficiently.


Why Should You Use BagistoNative with Next.js?

BagistoNative bridges the gap between your Next.js app and native mobile features, making it a powerful tool for creating cross-platform apps. Some of the key advantages include:

  • One Codebase: Build native iOS and Android apps from a single codebase.
  • Native Environment Detection: Automatically detect mobile environments.
  • Trigger Native Actions: Integrate features like native toasts, cart updates, and more.
  • Share UI Logic Across Platforms: Keep the user interface consistent between platforms.
  • Faster Development: Ship apps more quickly with fewer bugs.

This approach allows for faster and more scalable development across all platforms.


Prerequisites

Before starting, make sure you have the following:

  • Node.js 18 or higher
  • pnpm installed
  • A Next.js project (either new or existing)
  • Basic React knowledge

For a detailed guide on setting up BagistoNative with Next.js, refer to the full documentation.


Setting Up Your Project

1. Create or Use a Next.js Project

Start by creating a new Next.js project, or you can use the Bagisto Headless eCommerce Starter Kit one. Here’s how to create a new project:

npx create-next-app@latest my-native-mobile-app
cd my-native-mobile-app
Enter fullscreen mode Exit fullscreen mode

Alternatively, if you already have a Next.js project, you can use it directly.


2. Install BagistoNative Libraries

To integrate BagistoNative into your Next.js project, install the necessary libraries by running the following commands:

npm install @bagisto-native/core
npm install @bagisto-native/react
Enter fullscreen mode Exit fullscreen mode

Next, install all the dependencies:

pnpm install
Enter fullscreen mode Exit fullscreen mode

Make Your Next.js App Ready for Native Mobile

1. Add Environment Variables

If your app requires APIs or other configurations, make sure to add them to your .env.local file to keep your settings organized and secure.

2. Load Hotwire for Native Features

In your app/layout.tsx (or any other main layout file), add the following script tag to enable communication between your Next.js app and the native mobile shell:

<Script
    id="hotwire-loader"
    strategy="beforeInteractive"
    src="/hotwire/bundle.js"
/>
Enter fullscreen mode Exit fullscreen mode

This script is necessary to load the necessary JavaScript for native features.


Detect Native Mobile App Environment

BagistoNative provides helper functions to detect if your app is running within a native mobile environment.

Client-Side Detection

import { isTurboNativeUserAgent } from "@bagisto-native/core";

if (isTurboNativeUserAgent()) {
  // Adjust UI for native mobile users
}
Enter fullscreen mode Exit fullscreen mode

Server-Side Detection

import { headers } from "next/headers";
import { isTurboNativeUserAgent } from "@bagisto-native/core";

export default async function IsTurboNativeUserAgentFromServerComponent() {
  const headersList = await headers();
  const userAgent = headersList.get("user-agent") || "unknown";
  return isTurboNativeUserAgent(userAgent);
}
Enter fullscreen mode Exit fullscreen mode

This ensures your app renders correctly during server-side rendering.


Adding Native Mobile Features

BagistoNative offers built-in functions to easily integrate native mobile features into your Next.js app.

Update Cart Count in Native App

import { triggerCartCountValue } from "@bagisto-native/core";

triggerCartCountValue(cartCount);
Enter fullscreen mode Exit fullscreen mode

This will directly send the updated cart count to the native mobile app.

Show Native Toast Messages

import { triggerHotwireNativeToast } from "@bagisto-native/core";

triggerHotwireNativeToast("Item added to cart!");
Enter fullscreen mode Exit fullscreen mode

A native toast message will appear on the mobile app.

Share User Location

import React from "react";
import { triggerHotwireNativeLocationShare } from "@bagisto-native/core";

export default function LocationShareButton() {
  const handleShareLocation = () => {
    triggerHotwireNativeLocationShare();
  };

  return (
    <button onClick={handleShareLocation} style={{padding: 12, background: '#0070f3', color: '#fff', borderRadius: 6}}>
      Share My Location
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

When the button is tapped in the native app, the device’s location-sharing dialog will open.

Light/Dark Theme Toggle

import React, { useState, useEffect } from "react";

export default function ThemeModeToggle() {
  const [theme, setTheme] = useState("light");

  useEffect(() => {
    document.body.className = theme;
  }, [theme]);

  return (
    <button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
      Switch to {theme === "light" ? "Dark" : "Light"} Mode
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

This native theme mode works seamlessly for both web and mobile apps.


Search Component with Native Integration

Here’s an example of how to create a search component that works on both web and native mobile:

import { useRouter, useSearchParams } from "next/navigation";
import { MagnifyingGlassIcon, ArrowLeftIcon } from "@heroicons/react/24/outline";
import { useRef, useEffect } from "react";
import HotwireAppSearchComponent from "@/components/hotwire/components/HotwireAppSearchComponent";

export default function Search({ search, setSearch }) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const inputRef = useRef(null);

  function onSubmit(e) {
    e.preventDefault();
    setSearch && setSearch(false);

    const val = e.target;
    const search = val.search;
    const newParams = new URLSearchParams(searchParams.toString());

    if (search.value) {
      newParams.set("q", search.value);
    } else {
      newParams.delete("q");
    }

    router.push(createUrl("/search", newParams));
  }

  useEffect(() => {
    if (search && inputRef.current) {
      inputRef.current.focus();
      const length = inputRef.current.value.length;
      inputRef.current.setSelectionRange(length, length);
    }
  }, [search]);

  return (
    <>
      <HotwireAppSearchComponent />
      <form onSubmit={onSubmit}>
        <input ref={inputRef} placeholder="Search for products..." />
        <button aria-label="Search" type="submit">
          <MagnifyingGlassIcon />
        </button>
      </form>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

This Native Search component integrates smoothly with BagistoNative's search functionality.


Switching UI for Native Mobile

Use this code to customize the layout depending on whether the app is running on a mobile device:

<div className={isTurboNativeUserAgent() ? 'native-mobile-class' : 'web-class'}>
  {/* Content goes here */}
</div>
Enter fullscreen mode Exit fullscreen mode

This ensures that native mobile users get a tailored user experience.


Connecting Web and Native Mobile App

Cart Modal Bridge

import TurboCartModalBridge from "../hotwire/TurboCartModalBridge";
<TurboCartModalBridge onOpen={onOpen} />
Enter fullscreen mode Exit fullscreen mode

Search Router Bridge

import TurboSearchRouterBridge from "../hotwire/TurboSearchRouterBridge";
<TurboSearchRouterBridge />
Enter fullscreen mode Exit fullscreen mode

These bridges allow native apps to interact with your Next.js web app.


Running and Testing Your Native Mobile App

Start the development server with:

pnpm dev
Enter fullscreen mode Exit fullscreen mode

Now, you can test your app in:

  • A web browser
  • The iOS Turbo Native app
  • The Android Turbo Native app

*Generating APK and IPA for iOS *

After your app is ready, you can build the iOS and Android apps:

iOS Setup for BagistoNative Integration

To integrate BagistoNative with your iOS app, follow these steps:

Clone the iOS App Repository:
First, clone the iOS app repository for BagistoNative.

   git clone https://github.com/SocialMobikul/BagistoNative_iOS.git
   cd BagistoNative_iOS
Enter fullscreen mode Exit fullscreen mode

Open the iOS Project in Xcode:
Now, open the Example.xcodeproj project file in Xcode:

   open Example.xcodeproj
Enter fullscreen mode Exit fullscreen mode

Set the Base URL in iOS App:
In Xcode, find the following line and change it to your Next.js project URL (either your local network URL or a custom domain):

   let base_url = "http://192.168.x.x:3000" // or your custom domain
Enter fullscreen mode Exit fullscreen mode

Build & Run the iOS Application:
Select your simulator or a connected iPhone, then click Run in Xcode to build and deploy the iOS app.

After that, you can start testing your app’s functionality, including product displays, cart updates, checkout, and API connectivity.


For Android:

  1. Clone the Android repository: git clone https://github.com/SocialMobikul/BagistoNative_android.git
  2. Open the project in Android Studio.
  3. Set the Base URL in Android Studio.
  4. Build and run the Android app.

Conclusion

With Next.js and BagistoNative, you can quickly and easily build native iOS and Android apps using a single code

Top comments (0)