跳过主要内容
教程

将您的 Next.js 应用程序转换为 Capacitor 8

将您的现有 Next.js 15 网站应用程序转换为使用 Capacitor 8 的原生 iOS 和 Android 移动应用程序。配置静态导出、添加原生插件并部署到应用商店的完整指南。

文章来源

马丁·多纳迪尤

作者

瓦莱里亚

审稿人

乔丹

编辑

Convert Your Next.js App to iOS & Android with Capacitor 8

介绍

您已经有一个 Next.js 网络应用程序吗?本指南将教您如何将其转换为使用 Capacitor 8 — 最新版本,性能改进和新功能。

Capacitor wraps your web app in a native container, giving you access to device APIs like camera, filesystem, and push notifications while keeping your existing React codebase. Unlike React Native, you don’t need to rewrite anything — your Next.js code runs as-is.

您将学习:

  • 配置您的现有 Next.js 应用程序以静态导出
  • 在 Next.js 和 Capacitor 中添加 Capacitor 8 必备原生插件
  • 在 iOS 和 Android 模拟器上构建和测试
  • 快速开发
  • 解决常见的 iOS 布局问题(视口、安全区域、水平溢出)
  • 添加原生感觉的UI使用Capgo原生导航和过渡

想从零开始一个新项目?看看我们的 基于 Next.js 和 Capacitor 构建原生移动应用.

Benefits of Using Next.js and Capacitor

  • Code 重用性Next.js 让你能够编写可重用的组件并在你的 web 和移动应用之间共享 code,从而节省开发时间和精力。
  • Performance: Next.js offers built-in performance optimizations, such as server-side rendering and code splitting, ensuring fast loading times and a smooth user experience.
  • 原生功能: Capacitor 提供对本机设备功能的访问,如摄像头、地理位置等,使您能够构建功能丰富的移动应用。
  • 简化开发: 使用 Capacitor,您可以使用熟悉的 Web 技术开发和测试移动应用,降低学习曲线并简化开发流程。

前提条件

在开始之前,请确保您有:

  • Node.js 18+ 已安装
  • 一个现有的 Next.js 15+ 应用程序
  • Xcode (仅限 macOS,用于 iOS 开发)
  • 安卓 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;

该 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

您应该在项目根目录看到一个文件夹。这个文件夹包含所有静态文件,__CAPGO_KEEP_0__ 将将它们打包到您的原生应用中。 out Capacitor 8 的添加

Adding Capacitor 8 to Your Project

安装 __CAPGO_KEEP_0__ 核心和 __CAPGO_KEEP_1__:

  1. Install Capacitor core and CLI:
bun add @capacitor/core
bun add -D @capacitor/cli
  1. 安装常见的Capacitor插件:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/preferences

@__CAPGO_KEEP_0__/app:

  • @capacitor/应用@__CAPGO_KEEP_0__/keyboard:
  • @capacitor/键盘__CAPGO_KEEP_0__ 8
  • @capacitor/启动屏幕:管理原生启动屏幕
  • @capacitor/偏好设置:持久存储键值数据
  1. 初始化Capacitor项目详细信息:
bunx cap init my-app com.example.myapp --web-dir out

替换 my-app 用你的应用名称和 com.example.myapp 用你的应用ID(反向域名表示法)

  1. 创建或更新 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;
  1. 安装原生平台:
bun add @capacitor/ios @capacitor/android
  1. 添加原生平台文件夹:
bunx cap add ios
bunx cap add android

Capacitor 将创建 ios 并 android 项目根目录下的文件夹,包含本机项目。

要构建 Android 项目,您需要 安卓 Studio。要构建 iOS 项目,您需要一台带有 Xcode.

  1. 的 Mac
bun run mobile

构建和同步您的项目:

这将运行您的自定义脚本,构建 Next.js 项目并将静态文件同步到本机平台。

构建和部署本机应用程序: Xcode 已安装,并且对于 Android 应用程序,您需要安装 安卓 studio 已安装。另外,如果您打算在应用商店上发布您的应用程序,则需要为 iOS 和 Android 分别加入 Apple Developer Program 和 Google Play Console。

  1. 打开本机项目:

对于 iOS:

bun run mobile:ios

对于 Android:

bun run mobile:android

或者直接使用 Capacitor CLI:

bunx cap open ios
bunx cap open android
  1. 构建并运行应用程序:

android-studio-run

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

  • 在 Xcode 中,设置您的签名账户以将应用程序部署到真实设备。如您之前没有做过,Xcode 将指导您完成此过程(请注意,您需要加入 Apple Developer Program)。一旦设置好,单击“播放”按钮即可在连接的设备上运行应用程序。

恭喜! 您已成功将 Next.js 网站应用部署到移动设备。

nextjs-mobile-app
但是,开发期间还有更快的方法……

Capacitor 实时重载

在开发期间,您可以利用实时重载功能,立即在移动设备上看到更改。要启用此功能,请遵循以下步骤:

  1. 找到您的本地 IP 地址:
  • 在 macOS 上,在终端中运行以下命令:

    ipconfig getifaddr en0
  • 在 Windows 上运行:

    ipconfig

    在输出中查找 IPv4 地址。

  1. 更新您的 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;

替换 YOUR_IP_ADDRESS 使用您的本地 IP 地址(例如, 192.168.1.100).

  1. 将更改应用到您的本机项目:
bunx cap copy

该 copy 命令将 Web 文件夹和配置更改复制到本机项目中,而不更新整个项目。

  1. 使用 Android Studio 或 Xcode 在您的设备上重新构建并运行应用。

现在,无论您对 Next.js 应用程序进行哪些更改,移动应用程序都会自动重新加载以反映这些更改。

注意:如果您安装新插件或更改本机文件,则需要重新构建本机项目,因为实时重新加载仅适用于 Web code 更改。

使用 Capacitor 插件

Capacitor 插件使您能够从 Next.js 应用程序访问本机设备功能。让我们以 Share 插件为例: 安装 Share 插件: __CAPGO_KEEP_0__

  1. __CAPGO_KEEP_0__
bun add @capacitor/share
  1. 更新文件以使用分享插件: pages/index.js 同步更改与原生项目:
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>
  );
}
  1. 如前所述,当安装新插件时,我们需要执行同步操作,然后重新部署应用到设备上。要执行此操作,请运行以下命令:

或仅同步而不重建:

bun run mobile

重新构建并在设备上运行应用。

bunx cap sync
  1. 现在,当您点击“立即分享!”按钮时,原生分享对话框将出现,允许您与其他应用共享内容。

next-__CAPGO_KEEP_0__-share

next-capacitor-share
Next, you can make the app feel more native on iOS and Android with Capgo navigation and transitions, and fix common iOS layout issues that cause horizontal overflow or cropped safe areas. ## Native-feeling UI with Capgo Native Navigation and Transitions

Ionic Ionic 为了构建跨平台应用,但将其与 Next.js 集成起来是很hack的,并且当你已经有了 Tailwind CSS 4.

在 Next.js + Capacitor 应用中,为了实现原生移动体验,建议使用 Capgo 插件取代仅适用于 Web 的 UI 套件,如 Konsta UI:

  • @capgo/capacitor-原生导航 —— 原生导航栏、Liquid Glass iOS tab栏和 Android 模糊 tab栏样式。您的 Next.js 路由器保持路由状态,插件负责原生浏览器。
  • @capgo/capacitor-过渡 —— 在 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 tab栏(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') before router.push() 或 router.back()不要在原生导航拥有这些表面的情况下重复网页头部或底部。

请勿在原生导航拥有这些表面时重复Web页头部或页脚。 使用@capgo/capacitor原生导航 and 使用@capgo/capacitor过渡.

使用@__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-transitions

安全区域 在Tailwind CSS中使用安全区域,请使用@capgo/tailwind-capacitor (发布为) tailwind-capacitor (在 npm 上) safe-areas utilities 和其他 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-*) (手动添加) 在GitHub上提交一个PR.

(请在 __CAPGO_KEEP_0__ 上打开一个 PR)

(修复 iOS 布局问题 (视口, 安全区域, 和水平溢出)) overflow-x: hidden (如果内容在 iOS 上被裁剪, 位移, 或水平滚动, 添加更多或调整视口标签通常无法解决问题. 请按照以下顺序检查这些问题)

确保视口元标签正确应用

App 路由 (app/: export viewport from app/layout.tsx:

import type { Viewport } from 'next';

export const viewport: Viewport = {
  width: 'device-width',
  initialScale: 1,
  viewportFit: 'cover',
};

Pages 路由 (pages/: 将视口元标签放在 pages/_app.tsx, 不 _document.tsx (Next.js 可能不会像您期望的那样从 _document.tsx 中应用视口行为标签).

处理 iOS 安全区域

创建一个单一的应用 shell 并在其中应用安全区域填充 — 不要在多个嵌套组件中:

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. iOS 设备的安全区域内边距在头部、模态窗口和布局包装器中重复使用,通常会使 UI 看起来被裁剪或过大。

使用 @capgo/Tailwind-capacitor,您可以使用单个 shell 表达相同的内边距。 pt-safe pb-safe px-safe 设置 __CAPGO_KEEP_0__ iOS

设置CapacitoriOS contentInset 首先 never 在

In capacitor.config.ts) 来拥有安全区域: contentInsetMode: 'css'混合 __CAPGO_KEEP_0__ 的自动内容 inset 与 CSS

const config: CapacitorConfig = {
  appId: 'com.example.myapp',
  appName: 'my-app',
  webDir: 'out',
  ios: {
    contentInset: 'never',
  },
};

混合 Capacitor 自动内容内边距与 CSS env(safe-area-inset-*) padding 是双倍间距的常见原因。

找到真正溢出的元素

通常的凶手是使用 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, 重复的安全区域填充, 或固定宽度容器 —— 不是来自视口元标签本身。

性能优化

为了确保您的 Next.js 和 Capacitor 应用程序的最佳性能, 请考虑以下最佳实践:

  • 通过移除未使用的依赖项和资产来最小化应用大小。
  • 优化图像和其他媒体文件以减少加载时间。
  • 为组件和页面实现懒加载以提高初始加载性能。
  • 使用 Next.js 的服务器端渲染 (SSR) 来增强应用的加载速度和搜索引擎优化 (SEO)。
  • 利用 Capacitor 内置的优化功能,例如 WebView 缓存和应用打包。

结论

您已成功将现有的 Next.js 网站应用转换为使用 Capacitor 8 的原生 iOS 和 Android 应用。您的 Web 代码库现在可以在移动设备上运行,访问设备 API。

您实现了什么:

  • 配置 Next.js 以静态导出
  • 添加 Capacitor 8 以及必需的插件
  • 在 iOS 和 Android 模拟器上构建并部署
  • 为开发启用实时重载
  • 解决了常见的 iOS 布局问题(视口、安全区域、溢出)
  • 添加了具有本机感觉的 UI,使用 Capgo 本机导航和过渡

下一步:

  • 设置 Capgo 为无线更新而设置
  • 添加更多本机插件,如相机、地理位置或推送通知
  • 配置应用程序图标和启动屏幕以进行生产
  • 为 App Store 和 Google Play 提交做好准备

开始一个全新的项目?请查看 从头开始构建一个 Next.js 移动应用 获取一步一步的指引。

资源

了解如何使用 Capgo 快速构建更好的应用 注册免费账户 今天。

从将您的 Next.js 应用程序转换为 iOS &amp; Android 开始,继续使用 Capacitor 8

如果您正在使用 将您的 Next.js 应用程序转换为 iOS &amp; Android 使用 Capacitor 8 为了计划本机插件工作,连接它与 Capgo 插件目录 Capgo 插件目录中的产品工作流程 Capacitor 插件目录中的 Capgo 插件 Capacitor 插件目录中的 Capgo 插件的实现细节 添加或更新插件 添加或更新插件的实现细节 Ionic 企业插件替代方案 为 Ionic Enterprise Plugin Alternatives 的产品工作流程, 和 Capgo 原生构建 为产品工作流程在 Capgo 原生构建.

为 Capacitor 应用程序提供即时更新

当 web 层面的 bug 活跃时,通过 Capgo 将修复推送给用户,而不是等待几天的应用商店审批。用户在后台接收更新,而本地更改仍然在正常审批路径中。

来自马丁的人性化支持

立即开始

最新博客文章

Capgo 给您需要创建真正专业的移动应用程序所需的最佳见解。