跳过主要内容
教程

使用Capacitor 8将您的Next.js应用转换为iOS & Android

Transform your existing Next.js 15 web application into native iOS and Android mobile apps using Capacitor 8. A complete guide to configuring static export, adding native plugins, and deploying to app stores.

马丁·多纳迪厄

作者

瓦莱里亚

审稿人

乔丹

编辑

使用__CAPGO_KEEP_0__ 8将您的Next.js应用转换为iOS & Android

使用Capacitor 8将您的Next.js应用转换为iOS & Android

简介

已有 Next.js 网站应用? 本指南将教您如何将其转换为使用 Capacitor 的原生 iOS 和 Android 移动应用

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.

8 — 最新版本,性能改进和新功能。

  • Capgo
  • Add Capacitor 8 with essential native plugins
  • Capacitor
  • 将按原样运行。
  • 您将学习:
  • Add native-feeling UI with Capgo Native Navigation and Transitions

想从零开始一个新项目?请参阅我们的指南 从零开始构建一个Next.js移动应用.

Benefits of Using Next.js and Capacitor

  • Code Reusability: Next.js enables you to write reusable components and share code between your web and mobile apps, saving development time and effort.
  • 性能: Next.js offers built-in performance optimizations, such as server-side rendering and code splitting, ensuring fast loading times and a smooth user experience.
  • : Next.js提供了内置的性能优化,例如服务器端渲染和路由分割,确保快速加载时间和smooth用户体验。: Capacitor provides access to native device features like the camera, geolocation, and more, allowing you to build feature-rich mobile apps.
  • : Capacitor提供对原生设备功能的访问,例如摄像头、地理位置等,允许您构建功能丰富的移动应用。: With Capacitor, you can develop and test your mobile app using familiar web technologies, reducing the learning curve and streamlining the development process.

: 使用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;

这个 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 应用程序打包到本机移动容器中,请遵循以下步骤:

  1. 安装 Capacitor 核心和 CLI:
bun add @capacitor/core
bun add -D @capacitor/cli
  1. 安装您可能需要的常见 Capacitor 插件:
bun add @capacitor/app @capacitor/keyboard @capacitor/splash-screen @capacitor/preferences

这些插件提供了基本功能:

  • @capacitor/app: 处理应用程序生命周期事件(前台/后台,URLs)
  • @capacitor/keyboard: 在移动设备上控制键盘行为
  • @capacitor/splash-screen: 管理本机启动屏幕
  • @capacitor/preferences: 持久存储键值数据
  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 将在您的项目根目录下创建 iosandroid 文件夹,包含本机项目。

为了构建 Android 项目,您需要 Android Studio. For iOS, you need a Mac with Xcode.

  1. 构建和同步您的项目:
bun run mobile

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

构建和部署原生应用

要构建和部署您的原生移动应用,请遵循以下步骤: 要开发 iOS 应用,您需要安装 Xcode installed, and for Android apps, you need to have Android Studio 安装。此外,如果您计划将应用发布到应用商店,则需要在 iOS 上注册 Apple Developer Program,在 Android 上注册 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 插件: 更新文件以使用 Share 插件:

  1. 同步更改与原生项目:
bun add @capacitor/share
  1. __CAPGO_KEEP_0__ pages/index.js __CAPGO_KEEP_0__
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. __CAPGO_KEEP_0__

As mentioned earlier, when installing new plugins, we need to perform a sync operation and then redeploy the app to our device. To do this, run the following command:

bun run mobile

或者直接同步而不重建:

bunx cap sync
  1. 重建并在设备上运行应用。

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

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

## 使用__CAPGO_KEEP_1__原生导航和过渡实现原生感知UI 我已经工作了几年,使用 Ionic 来构建跨平台应用,但将其与Next.js集成起来是hacky的,并且当您已经有.

For a native mobile feel in a Next.js + Capacitor app, use Capgo plugins instead of web-only UI kits like Konsta 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' });

Wrap routed pages in cap-router-outlet, cap-page,和 cap-content,并调用 setDirection('forward')setDirection('back') context router.push()router.back()请勿在原生导航中重复网页头部或底部。

查看完整指南: 使用@capgo/capacitor-原生导航使用@capgo/capacitor-过渡.

安全区域使用Tailwind

在Tailwind CSS中,使用设备安全区域,请使用 @capgo/tailwind-capacitor (发布于 tailwind-capacitor 在npm上。它提供 safe-areas Capacitor友好的Tailwind插件:

bun add -D tailwind-capacitor

In 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 或调整视口标签通常无法解决问题。按照以下顺序检查这些问题。

确保视口元标签已正确应用

App Router (app/: export viewportapp/layout.tsx:

import type { Viewport } from 'next';

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

Pages Router (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);
}

在头部、模态对话框和布局包装器中重复的安全区域填充通常会使 UI 看起来被裁剪或过大。 .app-shell使用

@__CAPGO_KEEP_0__/tailwind-__CAPGO_KEEP_1__ @capgo/tailwind-capacitor,您可以使用类似于 pt-safe pb-safe px-safe 在单个 shell 上。

设置 Capacitor iOS contentInsetnever 首先

capacitor.config.ts,优先使用原生 inset 并让 CSS(或 Native Navigation 的) contentInsetMode: 'css')控制安全区域:

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

混合 Capacitor 自动内容 inset 与 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 为无线更新而设置
  • 添加更多本机插件,如摄像头、地理位置或推送通知
  • 配置应用程序图标和启动屏幕
  • 准备应用程序

开始一个全新的项目? 从头开始构建一个 Next.js 移动应用 资源

Next.js 文档

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

继续 Convert Your Next.js App to iOS &amp; Android with Capacitor 8

如果您正在使用 Convert Your Next.js App to iOS &amp; Android with Capacitor 8 为原生插件工作做好准备,连接它 Capgo 插件目录 在 Capgo 插件目录中了解产品工作流程 Capacitor 插件(由 Capgo 提供) 在 Capacitor 插件(由 Capgo 提供)中了解实现细节 添加或更新插件 在添加或更新插件中了解实现细节 Ionic 企业插件替代品 在 Ionic 企业插件替代品中了解产品工作流程 Capgo 原生构建 在 Capgo 原生构建中了解产品工作流程

Capacitor 应用的实时更新

当 web 层面的 bug 活跃时,通过 Capgo 将修复推送给用户,而不是等待几天的 app store 审核。用户在后台接收更新,而原生变化仍然在正常的审查路径中。

来自 Martin 的人性化支持

立即开始

最新博客文章

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