Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
  1. Home
  2. Blog
  3. Build it: screens and apps
  4. Mobile App Landing Page Template: QR Code and Store Links
Auf Deutsch lesen
  1. Blog
  2. Build it: screens and apps
  3. Mobile App Landing Page Template: QR Code and Store Links
Build it: screens and apps
Build it: screens and apps

Mobile App Landing Page Template: QR Code and Store Links

SR
Serban Rusu · Founder of Wingo UI
Nov 6, 2026 · 9 min read

On this page

0%
  1. What does a mobile app landing page need to do?
  2. How do you build the app download section in React?
    1. Which layout fits your app?
  3. How do you draw device shots in code instead of screenshots?
  4. How do you make one link that opens the right store?
  5. Can you use the official App Store and Google Play badges?
  6. When do you need the full Download Page template?
  7. Where does the Hero Section fit?
  8. What breaks on a 390px phone?
  9. How should the page end?
  10. Next step
  11. FAQ
    1. What should a mobile app landing page include?
    2. How do I send iPhone users to the App Store and Android users to Google Play from one link?
    3. Can I use my own button instead of the official App Store badge?
    4. Is there a free mobile app landing page template for Next.js?
    5. Should the QR code show on phones?

TL;DR

A mobile app landing page has one job: get the visitor to the right store in as few taps as possible. That means store buttons in the first screen on a phone, a QR code for desktop visitors (who cannot install from a laptop), and one short link that sends iPhones to the App Store and Android phones to Google Play. In Next.js, the Wingo UI App Download Section and Download Page template build that page from props, with a phone drawn in code that follows light and dark mode.

Published Nov 6, 2026

You built the app, the store listings are approved, and now you need a page that sells it. Search for a mobile app landing page template and you get HTML themes, Figma kits and a few React options. As of November 6, 2026, the Magic UI Pro Mobile template (opens in a new tab) runs on Next.js 14, React 18.3 and Tailwind 3.4 with store badges built in, TailGrids AppSpace (opens in a new tab) is a paid React and Tailwind template with download buttons in the hero, and a free Astro theme (opens in a new tab) fetches the rating, version and description from the App Store. None of their feature pages mentions two things an app page needs: a QR code for the desktop visitor and one link that opens the right store on each phone.

This guide covers what an app download page has to do, how two pieces of Wingo UI (the library we build) handle it, and what to check at 390px. The pieces are the App Download Section and the Download Page template, and the code targets the Next.js 16 App Router, React 19 and Tailwind v4.

What does a mobile app landing page need to do?

Get the visitor to the store. Everything else supports that one tap. Good app download page design comes down to four jobs, and each one changes with the device the visitor holds:

JobOn a phoneOn a desktop
Show the appA drawn phone or one screenshot, under the copyThe phone beside the copy, with a notification floating next to it
Get the installStore buttons in the first screen, at least 44px tallStore buttons plus a QR code to scan with the phone
Prove it is goodStore rating and review count under the buttonsThe same, plus features beside the phone
Answer doubtsFAQ: price, devices, offline, privacyThe same

The desktop row is the one most templates miss. Someone who found your app on a laptop cannot install it there. Without a QR code they have to search the store on their phone and hope they pick your app and not a clone with a similar icon.

How do you build the app download section in React?

Install the block. The CLI adds its dependencies too, including the QR Code component and the read-only rating:

bash
npx wingo-ui@latest add app-download-section

The block ships with "use client". Keep your instance in its own client file, as below, so the page that renders it stays a server component and can export metadata. Pass your real store links, the URL the QR code opens and your features:

tsx
// app/(marketing)/app-landing.tsx
"use client";
import Link from "next/link";
import { Bell, Play, Smartphone, WifiOff } from "lucide-react";
import { AppDownloadSection } from "@/components/blocks/app-download-section";
export function AppLanding() {
return (
<AppDownloadSection
headingAs="h1"
linkComponent={Link}
eyebrow="iOS and Android"
title="Your grocery list, shared with everyone at home"
description="Add an item on the bus, and it shows up on your partner's phone before they reach the store."
qrValue="https://acme.com/get"
rating={4.7}
reviewCount={3200}
radius="full"
stores={[
{ caption: "Download on the", label: "App Store", href: "https://apps.apple.com/app/id000000000", icon: <Smartphone /> },
{ caption: "Get it on", label: "Google Play", href: "https://play.google.com/store/apps/details?id=com.acme.list", icon: <Play /> },
]}
features={[
{ icon: <WifiOff />, title: "Works offline", description: "Edits sync when you are back online." },
{ icon: <Bell />, title: "Quiet notifications", description: "Only when someone adds to a list you follow." },
]}
/>
);
}

headingAs="h1" makes it the page's first heading, so the section can be the whole first screen. In split the features list sits between the description and the store buttons, so keep it to two short items (or pass features={[]}) if the buttons must be visible on a phone without scrolling. Use your real rating and review count from the store console, or set showRating={false} until you have them. A made-up 4.9 is the kind of claim a visitor checks in one tap.

Switch the layout between split, centered and card, then narrow the window below 1024px: the QR code disappears and the store buttons stay, sized for a thumb
$ npx wingo-ui@latest add app-download-section
ProApp Download Section docs

Which layout fits your app?

layout takes three values. split puts copy, features and downloads beside the phone and works as a hero. centered puts the heading and buttons on top with the phone between two feature columns, which suits a section lower on a longer page. card puts everything on a tone panel with the phone rising from its bottom edge, a good closing band. reverse moves the phone to the left in split from 1024px.

How do you draw device shots in code instead of screenshots?

The section draws the phone with CSS and design tokens: a frame, a camera pill, a status bar and a mini app with a progress card and a task list. Because it is drawn, it follows light and dark mode, stays sharp on every screen and never shows last quarter's UI. You change its copy through the phone prop (time, heading, user, tasks, the notification) and its frame color through phoneColor.

When your real app looks different, and it will, pass a screenshot through screen. It replaces only the inside of the phone, so the frame and the floating notification stay:

tsx
import Image from "next/image";
import { AppDownloadSection } from "@/components/blocks/app-download-section";
<AppDownloadSection
screen={<Image src="/shots/list-home.png" alt="" width={390} height={844} className="size-full object-cover" />}
phoneColor="#1F2937"
/>

The alt is empty because screen readers hear the phone as one image and skip its screen. The default description talks about the drawn task list, so describe your screenshot instead with labels={{ phone: "..." }}. Export the screenshot at the phone's aspect ratio so object-cover crops nothing important.

How do you make one link that opens the right store?

The QR code, your ads and your emails should all point to one URL. Add a route handler that reads the user agent and redirects:

ts
// app/get/route.ts
const APP_STORE = "https://apps.apple.com/app/id000000000";
const GOOGLE_PLAY = "https://play.google.com/store/apps/details?id=com.acme.list";
export function GET(request: Request) {
const ua = request.headers.get("user-agent") ?? "";
if (/iphone|ipod/i.test(ua)) return Response.redirect(APP_STORE, 302);
if (/android/i.test(ua)) return Response.redirect(GOOGLE_PLAY, 302);
// ipads report a mac user agent by default, so they land on the download page
return Response.redirect(new URL("/download", request.url), 302);
}

A 302 keeps the target easy to change later. Scanning the QR code on the landing page now opens the store listing directly on the visitor's phone, with no second search. For QR styling, such as a logo in the center that still scans, see our React QR code with logo guide.

On iPhone you can also add Safari's Smart App Banner. In Next.js it is one metadata field, which renders the apple-itunes-app meta tag:

tsx
// app/(marketing)/page.tsx
import type { Metadata } from "next";
import { AppLanding } from "./app-landing";
export const metadata: Metadata = {
title: "Acme List for iPhone and Android",
itunes: { appId: "000000000" },
};
export default function Page() {
return <AppLanding />;
}

Can you use the official App Store and Google Play badges?

Yes, if you follow each store's rules. As of November 6, 2026, the App Store badge guidelines in Apple's marketing guidelines (opens in a new tab) say to use only the badge artwork Apple provides, not to modify, angle or animate it, to keep clear space of a quarter of the badge height around it, to show it at least 40px tall on screen and to place it first when other store badges appear. Google's Google Play badge guidelines (opens in a new tab) ask for the same quarter-height clear space, a minimum height of 28px, and a Google Play badge the same size or larger than the other badges next to it.

The App Download Section does not ship those logos. Its store buttons are generic links with a lucide glyph and the store name, 56px tall on phones and 52px from 640px. To use the official artwork, hide the built-in buttons and pass your badges as actions:

tsx
<AppDownloadSection
stores={[]}
actions={
<div className="flex flex-wrap items-center gap-3">
<a href="https://apps.apple.com/app/id000000000">
<img src="/badges/app-store.svg" alt="Download on the App Store" className="h-12 w-auto" />
</a>
<a href="https://play.google.com/store/apps/details?id=com.acme.list">
<img src="/badges/google-play.svg" alt="Get it on Google Play" className="h-12 w-auto" />
</a>
</div>
}
/>

Both images get the same height, with the App Store badge first and gap-3 (12px) of space, which covers a quarter of a 48px badge. If your Google Play file carries transparent padding, crop it or raise its height so the badge does not render smaller than Apple's.

When do you need the full Download Page template?

Use it when the app also ships for Mac, Windows, Linux, a browser or the command line. The Download Page template composes the App Download Section with an OS-aware hero, a platform picker, install commands, checksums, release notes and system requirements. After hydration its main button follows the visitor's device, so an iPhone sees "Download on the App Store" and an Android phone "Get it on Google Play" instead of a Mac download. The server always renders macOS, so the markup never mismatches, and the client catches iPads (which report a Mac user agent) with a touch check the server cannot do.

This version is pinned to iPhone: the hero button offers the App Store, and the iPhone tab in the picker shows a QR code and three install steps. Press the download button to see the thanks state
$ npx wingo-ui@latest add download-page
ProDownload Page docs

The template does not navigate on its own. It calls onDownload(platform, variant, channel) and you decide where to go:

tsx
// app/(marketing)/download/download-route.tsx
"use client";
import Link from "next/link";
import { DownloadPage } from "@/components/templates/download-page";
const STORES: Record<string, string> = {
"ios:app-store": "https://apps.apple.com/app/id000000000",
"android:play": "https://play.google.com/store/apps/details?id=com.acme.list",
};
export function DownloadRoute() {
return (
<DownloadPage
header={false}
footer={false}
linkComponent={Link}
ctaTone="brand"
mobileProps={{ qrValue: "https://acme.com/get" }}
onDownload={(platform, variant) => {
const url = STORES[`${platform}:${variant}`];
if (url) window.open(url, "_blank", "noopener");
}}
/>
);
}

Pass your own platforms array to list only what you ship, and turn off the sections you have no content for: showRequirements, showEnterprise and showFeatures (the desktop features) all take false.

Where does the Hero Section fit?

Use the Hero Section instead of the App Download Section at the top when the app is one part of a product that also runs on the web, so the first screen sells the product and the app comes lower. Point its primary action at the store link and put a phone screenshot in media:

tsx
import Image from "next/image";
import Link from "next/link";
import { HeroSection } from "@/components/blocks/hero-section";
<HeroSection
layout="split"
linkComponent={Link}
title="Plan the week together, on any device"
labels={{ primary: "Get the app", secondary: "Open in the browser" }}
hrefs={{ primary: "/get", secondary: "/sign-in" }}
media={<Image src="/shots/list-home.png" alt="The Acme List app on a phone" width={780} height={1688} className="mx-auto h-auto w-64" />}
/>

Then an App Download Section with layout="centered" further down repeats the stores and adds the QR code. Our shadcn hero section guide covers the other hero layouts.

What breaks on a 390px phone?

Usually the first screen: too much copy above the store buttons pushes them below the fold. Check these on a real phone before you launch:

  • The first screen. Title, one line of description and both store buttons visible without scrolling. If not, cut the description.
  • The buttons. At least 44px tall and far enough apart that a thumb does not hit both. The section's buttons are 56px tall on phones, share the row and wrap onto two lines when it gets too narrow.
  • The QR code. Hidden. The section shows it from 1024px only, which is right: a phone cannot scan itself.
  • The picture. The drawn phone goes under the copy and the floating notification hides at narrow widths, so nothing forces a sideways scroll.
  • Web app visitors. If your product is also a PWA, do not stack an install prompt on top of the store buttons. Our React PWA install prompt guide covers when each one makes sense.

How should the page end?

With the questions people ask before they install, then one last download button. Cover the doubts first: is it free, which devices, does it work offline, what happens to my data. The free FAQ Section takes them as items and can emit FAQ JSON-LD with jsonLd. The free CTA Section closes the page with a solid band (variant="inverted", the default); point its hrefs.primary at /get.

For a whole marketing site around the app, the Landing Page template composes the same marketing sections. More full pages are in the Build it category, starting from its pillar, the Next.js admin dashboard tutorial.

Next step

The App Download Section, Download Page template and Hero Section come with Pro ($8 a month, $80 a year or $150 once); the FAQ and CTA sections are free with a free account. Start with npx wingo-ui@latest add app-download-section, pass your store links and the /get URL, and scan the QR code with your own phone before anyone else does.

Components in this post

  • App Download Section

    A mobile app promo: a drawn phone with a mini app, store buttons, a QR code to the download page, the rating and feature bullets.

    Pro
  • Download Page

    A React app download page template: an OS-aware download hero, drawn desktop and phone apps, a platform picker with checksums, and FAQ.

    Pro
  • Hero Section

    A React hero section for a landing or product page: an announcement pill, a big title, two actions, social proof and a product shot drawn in code.

    Pro
  • QR Code

    A React QR code generator with rounded or dotted modules, soft eyes, a center logo, any colors, a caption and one-tap PNG or SVG export.

    Pro
  • FAQ Section

    A React FAQ section for marketing pages: an accordion, a split layout, an open grid or expandable cards, with topics and live search.

    Free

FAQ

What should a mobile app landing page include?

A headline with store buttons in the first screen, a picture of the app, three or four features, proof such as the store rating, an FAQ about price, devices and privacy, and a closing call to action. Desktop visitors also need a QR code, because they cannot install a phone app from a laptop.

How do I send iPhone users to the App Store and Android users to Google Play from one link?

Add a route handler such as /get that reads the user agent and redirects with a 302: iPhone and iPod to the App Store, Android to Google Play, everything else to your download page. Use that one URL in the QR code, ads and emails.

Can I use my own button instead of the official App Store badge?

Not for the App Store: Apple's marketing guidelines say to use only the badge artwork Apple provides and not to modify it. The App Download Section draws generic store buttons with a glyph and the store name, so for the official badges pass an empty stores array and put the badge images in the actions prop.

Is there a free mobile app landing page template for Next.js?

In Wingo UI the App Download Section, Download Page template and Hero Section are Pro, while the FAQ Section, CTA Section and Marketing Header are free with a free account. Outside Next.js, astro.build lists a free Mobile App Landing Page theme built with Astro and React (checked November 6, 2026).

Should the QR code show on phones?

No. A visitor on a phone cannot scan their own screen, so the code only wastes space. The App Download Section shows it from 1024px and gives phones the store buttons only.

Try it in your project

App Download Section

Pro

A mobile app promo: a drawn phone with a mini app, store buttons, a QR code to the download page, the rating and feature bullets.

75 components free, no account needed. Pro from $8 a month.

Open App Download Section liveSee pricing
  • Mobile apps
  • Landing page
  • Templates
  • Next.js

Share

SR

About the author

Serban Rusu

Founder of Wingo UI

Serban Rusu founded Wingo UI. He builds its component library, CLI and MCP server, and writes about React interfaces for phones and AI coding agents.

More from Serban
Keep reading

Related posts

All posts
Build it: screens and apps

AI SaaS Landing Page Template: The 4 Sections It Needs

An AI SaaS landing page template needs four sections a generic SaaS page skips: a demo that answers, a data training policy, usage pricing and named models.

SRSerban Rusu·Nov 6, 2026·9 min read
Build it: screens and apps

Nextjs SaaS Landing Page: What Each Section Must Prove

Build a nextjs saas landing page section by section: what the hero, proof, features, pricing and FAQ must prove, what to cut, and how each reads on a phone.

SRSerban Rusu·Oct 16, 2026·11 min read
Building UI with AI agents

Claude Code Landing Page That Does Not Look AI-Made

Build a Claude Code landing page from real sections: connect them through MCP, set tokens and a rules file, then prompt one section at a time and check it.

SRSerban Rusu·Nov 5, 2026·11 min read
Newsletter

Get new posts by email

New posts, product news and occasional offers from Wingo UI. We count clicks to keep it relevant.

No spam. Unsubscribe at any time.

WingoUI

Animated, configurable, mobile-first React components and blocks. Copy the source, make it yours, and let your coding agent build with it.

Product

  • Components
  • Templates
  • Pricing
  • AI agents
  • For teams
  • Theme generator

Resources

  • Docs
  • Contact
  • Programs
  • Blog
  • Changelog
  • Changelog RSS
  • llms.txt

Compare

  • Wingo UI vs paid kits
  • Wingo UI vs shadcn/ui
  • shadcn/ui alternatives
  • MUI alternatives
  • Tailwind Plus alternatives
  • Magic UI alternatives
  • Free components

Legal

  • Terms
  • Privacy
  • Refunds
  • License
  • Imprint

Component categories

  • Buttons & Actions
  • Inputs
  • Forms
  • Navigation
  • Overlays
  • Feedback
  • Data Display
  • Tables & Lists
  • Charts & Stats
  • Layout
  • Media
  • AI Kit
  • Text & Effects
  • Mobile
  • Commerce
  • Marketing Sections
  • Blocks
  • Hooks & Utilities

© 2026 Wingo UI

Wingo UI