介绍
您有一个现有的 Next.js 网站应用程序?本指南将教您如何将其转换为原生 iOS 和 Android 移动应用程序使用 Capacitor 8 — 最新版本,性能改进和新功能。
Capacitor 将您的 Web 应用程序包装在原生容器中,给您访问设备 API 的权限,如相机、文件系统和推送通知,而不改变您的现有 React 代码库。与 React Native 不同,您不需要重写任何内容 ——您的 Next.js code 将保持不变。
您将学到:
- 配置您的现有 Next.js 应用程序以静态导出
- 添加 Capacitor 8 以必要的原生插件
- 在 iOS 和 Android 模拟器上构建和测试
- 为更快的开发启用实时重载
- 修复常见的 iOS 布局问题(视口、安全区域、水平溢出)
- 使用 Capgo 原生导航和过渡添加原生感知 UI
想从头开始一个新项目?查看我们的指南 从头开始构建一个 Next.js 移动应用.
使用 Next.js 和 Capacitor 的好处
- Code 可重用性:通过 Next.js,您可以编写可重用的组件并在您的 Web 和移动应用之间共享 code,节省开发时间和精力。
- 性能:Next.js 提供内置的性能优化,例如服务器端渲染和 code 分割,确保快速加载时间和smooth 用户体验。
- 原生功能: Capacitor 提供对本机设备功能的访问,如摄像头、地理位置等,使您能够构建功能丰富的移动应用。
- 简化开发: 使用 Capacitor,您可以使用熟悉的 Web 技术开发和测试移动应用,减少学习曲线并简化开发流程。
前置条件
开始之前,请确保您有:
- Node.js 18+ 已安装
- 一个现有的 Next.js 15+ 应用
- Xcode (仅限 macOS,用于 iOS 开发)
- Android Studio (用于 Android 开发)
配置 Next.js 应用程序以支持移动端
首先,需要配置 Next.js 应用程序以静态输出。Capacitor 需要静态 HTML/JS/CSS 文件来打包到原生应用中。
打开你的 next.config.js (或 next.config.ts)文件并添加输出配置:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true,
},
};
module.exports = nextConfig;
The output: 'export' 设置告诉 Next.js 生成静态 HTML 文件,并 images: { unoptimized: true } 绕过 Next.js 的图像优化,这需要一个服务器。
重要提示: 如果你正在使用需要服务器的功能(例如API路由、带有数据获取的服务器组件等),你需要将这些功能重构为使用客户端替代品或外部 API。
为移动设备添加脚本 package.json:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"mobile": "bun run build && bunx cap sync",
"mobile:ios": "bun run mobile && bunx cap open ios",
"mobile:android": "bun run mobile && bunx cap open android"
}
}
通过运行:
bun run build
您应该看到一个 out 根目录下的文件夹,这个文件夹包含了所有将被 Capacitor 打包到原生应用中的静态文件。
在您的项目中添加 Capacitor 8
将您的 Next.js 应用打包到原生移动容器中,请遵循以下步骤:
- 安装 Capacitor 核心和 CLI:
bun add @capacitor/core
bun add -D @capacitor/cli
- 安装您可能需要的常见 Capacitor 插件:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/preferences
这些插件提供了基本功能:
- @capacitor/app: 处理应用程序生命周期事件(前台/后台,URL)
- @capacitor/keyboard: 移动设备上控制键盘行为
- @capacitor/splash-screen: 管理原生启动屏幕
- @capacitor/preferences: 持久存储键值数据
- 初始化 Capacitor 以及您的项目详细信息:
bunx cap init my-app com.example.myapp --web-dir out
替换 my-app 为您的应用名称 com.example.myapp 为您的应用 ID(反向域名表示法)
- 创建或更新
capacitor.config.ts文件以获取正确的配置:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'out',
plugins: {
SplashScreen: {
launchShowDuration: 2000,
launchAutoHide: true,
androidScaleType: 'CENTER_CROP',
showSpinner: false,
splashFullScreen: true,
splashImmersive: true,
},
},
};
export default config;
- 安装本机平台:
bun add @capacitor/ios @capacitor/android
- 添加本机平台文件夹:
bunx cap add ios
bunx cap add android
Capacitor 将创建 ios 和 android 文件夹在您的项目根目录中包含本机项目。
要构建 Android 项目,您需要 Android Studio。对于 iOS,您需要一台 Xcode.
- 构建和同步您的项目:
bun run mobile
这将运行您的自定义脚本,构建 Next.js 项目并同步静态文件与本机平台。
构建和部署本机应用
要构建和部署您的本机移动应用,请遵循以下步骤: 要开发 iOS 应用,您需要 Xcode 需要安装 Xcode,针对 Android 应用,需要安装 Android Studio 此外,如果您打算在应用商店上发布您的应用,则需要为 iOS 和 Android 分别加入 Apple Developer Program 和 Google Play Console。
- 打开本机项目:
针对 iOS:
bun run mobile:ios
针对 Android:
bun run mobile:android
或者直接使用 Capacitor CLI:
bunx cap open ios
bunx cap open android
- 构建并运行应用:

-
在 Android Studio 中,等待项目准备就绪,然后单击“运行”按钮将应用部署到连接的设备或模拟器中。

-
在 Xcode 中,设置您的签名账户以在真实设备上部署应用。如果您之前没有这样做过,Xcode 将指导您完成此过程(请注意,您需要注册 Apple Developer Program)。一旦设置好,点击“Play”按钮即可在连接的设备上运行应用。
恭喜您!您已成功将 Next.js 网站应用部署到移动设备。
Capacitor 实时重载
在开发期间,您可以利用实时重载功能来实时在移动设备上看到变化。要启用此功能,请遵循以下步骤:
- 找到您的本地 IP 地址:
-
在 macOS 上,在终端中运行以下命令:
ipconfig getifaddr en0 -
在 Windows 上运行:
ipconfig在输出中查找 IPv4 地址:
- 更新您的
capacitor.config.ts指向您的开发服务器:
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'my-app',
webDir: 'out',
server: {
url: 'http://YOUR_IP_ADDRESS:3000',
cleartext: true,
},
};
export default config;
替换为您的本地 IP 地址(例如, YOUR_IP_ADDRESS 将更改应用到您的原生项目: 192.168.1.100).
- 命令将复制 Web 文件夹和配置更改到原生项目,而不更新整个项目。
bunx cap copy
使用 Android Studio 或 Xcode 在设备上重新构建并运行应用。 copy 现在,无论何时您对 Next.js 应用程序进行更改,移动应用程序都会自动重新加载以反映这些更改。
- 注意:如果您安装新插件或更改原生文件,则需要重新构建原生项目,因为实时重新加载仅适用于 Web __CAPGO_KEEP_0__ 更改。
使用 __CAPGO_KEEP_0__ 插件
code 插件允许您从 Next.js 应用程序访问原生设备功能。让我们以 "Share" 插件为例:
Using Capacitor Plugins
Note: If you install new plugins or make changes to native files, you’ll need to rebuild the native project since live reloading only applies to web Capacitor changes. Using __CAPGO_KEEP_0__ Plugins __CAPGO_KEEP_0__ plugins allow you to access native device features from your Next.js app. Let’s explore how to use the
- 安装 Share 插件:
bun add @capacitor/share
- 更新
pages/index.js文件以使用 Share 插件:
import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { Share } from '@capacitor/share';
export default function Home() {
const share = async () => {
await Share.share({
title: 'Open Youtube',
text: 'Check new video on youtube',
url: 'https://www.youtube.com',
dialogTitle: 'Share with friends',
});
};
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Capgo!</a>
</h1>
<p className={styles.description}>
<h2>Cool channel</h2>
<button onClick={() => share()}>Share now!</button>
</p>
</main>
</div>
);
}
- 同步更改与原生项目:
如前所述,当安装新插件时,我们需要执行同步操作,然后重新部署应用到设备上。要执行此操作,请运行以下命令:
bun run mobile
或仅同步而不重建:
bunx cap sync
- 重建并在设备上运行应用。
现在,当您点击“立即分享!”按钮时,原生分享对话框将出现,允许您与其他应用共享内容。
我已经与 Ionic 为了构建跨平台应用,但将其与 Next.js 集成起来是hacky的,并且当你已经有了 Tailwind CSS 4.
为了在 Next.js + Capacitor 应用中获得原生移动体验,使用 Capgo 插件而不是仅限于 web 的 UI 套件,如 Konsta UI:
- @capgo/capacitor-native-navigation — 原生导航栏、Liquid Glass iOS 的标签栏、以及 Android 的模糊标签栏样式。你的 Next.js 路由器保留了路由状态;插件拥有原生浏览器的控制权。
- @capgo/capacitor-transitions — 在 WebView层中实现了Ionic风格的页面过渡和iOS的边缘滑动返回,且不需要采用Ionic UI。
安装两者:
bun add @capgo/capacitor-native-navigation @capgo/capacitor-transitions
bunx cap sync
配置原生导航以使用 CSS inset 模式,使 web 内容尊严原生导航栏:
import { NativeNavigation } from '@capgo/capacitor-native-navigation';
await NativeNavigation.configure({
contentInsetMode: 'css',
animationDuration: 360,
glass: {
effect: 'liquidGlass',
},
});
渲染一个Liquid Glass标签栏(iOS使用系统渲染;Android使用模糊的WebView背景):
await NativeNavigation.setTabbar({
selectedId: 'home',
labelVisibilityMode: 'labeled',
icons: true,
colors: { dynamic: true },
tabs: [
{ id: 'home', title: 'Home', icon: { svg: '...' } },
{ id: 'settings', title: 'Settings', icon: { svg: '...' } },
],
});
await NativeNavigation.addListener('tabSelect', ({ id }) => {
router.push(`/${id}`);
});
在应用壳中添加原生页面过渡:
import '@capgo/capacitor-transitions';
import { initTransitions, setDirection, setupRouterOutlet } from '@capgo/capacitor-transitions/react';
initTransitions({ platform: 'auto' });
将路由页面包裹在 cap-router-outlet, cap-page,和 cap-content,和调用 setDirection('forward') 或 setDirection('back') 前 router.push() 或 router.back(). 不要在本机导航时重复显示网页头部或底部。
查看完整指南: 使用@capgo/capacitor-native-navigation 和 使用@capgo/capacitor-转换.
安全区域与Tailwind
在Tailwind CSS中,使用设备安全区域 @capgo/tailwind-capacitor (发布为 tailwind-capacitor 在 npm 上发布。它提供 safe-areas 工具和其他 Capacitor 友好的 Tailwind 插件:
bun add -D tailwind-capacitor
在 styles/globals.css:
@import 'tailwindcss';
@plugin "@capgo/tailwind-capacitor/platform";
@plugin "@capgo/tailwind-capacitor/safe-areas";
使用工具,如 pt-safe, pb-safe,和 px-safe 代替手动 env(safe-area-inset-*) 通过手动。该项目正在积极开发中 — 如果您的 Next.js 设置缺少某些内容,请 在 GitHub 上打开一个 PR.
修复 iOS 布局问题(视口、安全区域和水平溢出)
如果内容看起来被裁剪、偏移或水平滚动在 iOS 上,添加更多 overflow-x: hidden 或仅仅是调整 viewport 标签通常无法解决问题。按照以下检查顺序进行工作。
确保 viewport 元数据标签正确应用
App Router (app/从 viewport Pages Router app/layout.tsx:
import type { Viewport } from 'next';
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
viewportFit: 'cover',
};
将 viewport 元数据标签放在 (pages/不 pages/_app.tsx(Next.js 可能不会像您期望的那样应用标签以实现 viewport 行为) _document.tsx 从根 wrapper 中只处理 iOS 安全区域 _document.tsx 创建一个单一的应用 shell,并在其中应用安全区域填充 — 不要在多个嵌套组件中:
__CAPGO_KEEP_0__
__CAPGO_KEEP_1__
html,
body,
#__next {
width: 100%;
min-height: 100%;
margin: 0;
padding: 0;
overflow-x: hidden;
}
* {
box-sizing: border-box;
}
.app-shell {
min-height: 100dvh;
width: 100%;
padding-top: env(safe-area-inset-top);
padding-right: env(safe-area-inset-right);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
}
将所有页面内容包裹在 .app-shell在头部、模态窗口和布局包装器中重复使用安全区域填充,通常会使 UI 看起来被裁剪或过大。
使用 @capgo/tailwind-capacitor,您可以使用类似于 pt-safe pb-safe px-safe 的工具来表示相同的填充。
Set Capacitor iOS contentInset 设置__CAPGO_KEEP_0__ iOS never 为
首选 capacitor.config.ts在 contentInsetMode: 'css',优先使用原生 inset 禁用并让 CSS (或 Native Navigation 的 )拥有安全区域:
const config: CapacitorConfig = {
appId: 'com.example.myapp',
appName: 'my-app',
webDir: 'out',
ios: {
contentInset: 'never',
},
};
混合Capacitor的自动内容内边距与CSS env(safe-area-inset-*) 使用CSS内边距引起的双倍间距是常见问题。
找到真正溢出的元素
通常是使用 100vw, Tailwind w-screen, 固定像素宽度或宽度过大的 min-width.
在Safari Web Inspector中运行:
[...document.querySelectorAll('*')]
.filter(el => el.scrollWidth > document.documentElement.clientWidth)
.map(el => ({
el,
tag: el.tagName,
class: el.className,
scrollWidth: el.scrollWidth,
clientWidth: document.documentElement.clientWidth,
}));
使用Tailwind时,替换 w-screen 为 w-full 尽可能使用。许多水平溢出问题来自 100vw / w-screen, 重复的安全区域内边距或固定宽度容器,而不是视口元标签本身。
性能优化
To ensure optimal performance of your Next.js and Capacitor app, consider the following best practices:
- 为了确保您的 Next.js 和 __CAPGO_KEEP_0__ 应用程序的最佳性能,请考虑以下最佳实践:
- Minimize the app size by removing unused dependencies and assets.
- 通过移除未使用的依赖项和资产来最小化应用程序大小。
- Optimize images and other media files to reduce loading times.
- Leverage Capacitor’s built-in optimizations, such as web view caching and app bundling.
Implement lazy loading for components and pages to improve initial load performance.
You’ve successfully converted your existing Next.js web application into native iOS and Android apps using Capacitor 8. Your web codebase now runs natively on mobile devices with access to device APIs.
Use server-side rendering (SSR) with Next.js to enhance the app’s loading speed and search engine optimization (SEO).
- 使用 Next.js 的服务器端渲染(SSR)来增强应用程序的加载速度和搜索引擎优化(SEO)。
- Leverage Capacitor’s built-in optimizations, such as web view caching and app bundling.
- 利用 __CAPGO_KEEP_0__ 的内置优化功能,例如 Web 视图缓存和应用程序打包。
- 启用开发时的实时重载
- 修复了常见的 iOS 布局问题(视口、安全区域、溢出)
- 添加了具有 Capgo 本地导航和过渡效果的原生式 UI
下一步骤:
- 设置 Capgo 用于在应用商店重新提交应用之前进行无线更新
- 添加更多原生插件,如摄像头、地理位置或推送通知
- 配置应用图标和启动屏幕以进行生产
- 为 App Store 和 Google Play 提交应用做好准备
要开始一个全新的项目?请查看 从头开始构建一个 Next.js 移动应用 为您提供一个引导式教程。
资源
- Next.js 文档
- @capgo/capacitor-native-navigation — Liquid Glass tab bar 和原生 chrome
- Capacitor 8 文档
- @capgo/capacitor-transitions — 原生感知的页面过渡
- @capgo/tailwind-capacitor — Tailwind safe-area utilities for Capacitor
- Capgo - Live Updates for Capacitor Apps
了解如何使用 Capgo 快速构建更好的应用 注册一个免费账户 今天。
继续使用 Convert Your Next.js App to iOS & Android with Capacitor 8
如果您正在使用 使用 Convert Your Next.js App to iOS & Android with Capacitor 8 为原生插件工作计划,连接它到 Capgo 插件目录 在 Capgo 插件目录中 Capacitor Plugins by Capgo for the implementation detail in Capacitor Plugins by Capgo, 添加或更新插件 添加或更新插件 Ionic Enterprise 插件替代品 为 Ionic Enterprise 插件替代品中的产品工作流程 Capgo 本机构建 为 Capgo 本机构建中的产品工作流程