Redirecting mobile users to App or Play Store in NextJS
Tags: nextjs, mobile, javascript, typescript
Published: 2023-11-27 19:53:11

So here is the case: you have a mobile app for both iOS and Android and you have decided to promote it. While you could simply ask people to search for it on App Store or Google Play, that's not ideal. But you also don't want to use multiple URLs and let the audience write/click/scan the appropriate one for them. 

Also, a substantial amount of users don't know if they use iOS or Android. They are simply interested in testing your app but unless they can just click a button to get it, you will loose them. Or at least make them irritated before they even installed your app.

While there are many services that provide a way to use a single URL and QR-code that redirects a mobile user to the correct app store depending on her platform, it is extremely easy to implement a homegrown solution. Let us see how this can be done when using Next.

# Overview of the Approach

The solution involves two main components in a NextJS application:

- **The Middleware** (`middleware.ts`): This file is responsible for detecting the user's device type and redirecting them to the correct app store.
- **A Placeholder Page** (`app/get.tsx`): This page serves as a trigger for the middleware.

Let's delve into the details of these components.

# Creating the Middleware (middleware.ts)

The middleware is the heart of our solution. It detects the user's device type and then redirects them to the appropriate store. Here’s the breakdown:

```typescript
import type { NextRequest } from 'next/server'
import { NextResponse, userAgent } from 'next/server'

export function middleware(req: NextRequest) {
  const { ua } = userAgent(req)

  if (/iP(hone|ad|od)/.test(ua)) {
    return NextResponse.redirect(
      'https://apps.apple.com/in/app/yourapp/id123456789'
    )
  } else if (/Android/.test(ua)) {
    return NextResponse.redirect(
      'https://play.google.com/store/apps/details?id=com.yourapp'
    )
  } else {
    return NextResponse.redirect('https://yourdomain.com')
  }
}

export const config = {
  matcher: '/get',
}
```

We use a middleware to return the redirect as early as possible before rendering anything to the user.

Key Points:
- **Device Detection**: We use regular expressions to determine whether the user's device is an iPhone, iPad, iPod, or Android.
- **Redirection**: Depending on the device type, we redirect the user to either the App Store or Google Play Store.
- **Fallback**: For non-mobile users, we redirect them to a default website.

For iOS the redirect should open App Store straight away, while on Android the user will be taken to the web version of Play Store but a modal will be displayed about opening your app in the native Play Store app. There are solutions to this which involve different ways of launching Play store but that's for another article.

# Setting Up the Placeholder Page (app/get.tsx)

This page serves as a trigger for the middleware. This would normally never be executed unless the middleware for some reason fails to redirect the user. It's a simple component that redirects to the home page:

```typescript
import { redirect } from 'next/navigation'

export default async function DownloadAppRoute() {
  redirect('/')

  return <div></div>
}
```

# Own the contact points

That's it! From here you can evolve this solution futher, for example by adding stats. One easy tweak could be to change the fallback to a page about your app.

By hosting the solution yourself you maintain control of the contact point to the end-user, any SEO-boost is given to your domain and any QR-codes you use will be pointed to your domain directly. This is in contrast to using 3rd party services where the redirect goes through their  domains, so if you ever stop paying the invoices any printed links or QR-codes will be rendered useless.