跳过主要内容
教程

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

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

简介

已有 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 文件夹,包含本机项目。

To build the Android project, you need Android StudioFor iOS, you need a Mac with Xcode.

  1. Build and sync your project:
bun run mobile

This runs your custom script that builds the Next.js project and syncs the static files with the native platforms.

Building and Deploying Native Apps

To build and deploy your native mobile app, follow these steps: To develop iOS apps, you need to have Xcode installed, and for Android apps, you need to have Android Studio

  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__

如前所述,安装新插件时,我们需要执行同步操作,然后重新部署应用到设备上。要实现此操作,请运行以下命令:

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-*) 通过手动添加 open a PR on GitHub.

修复 iOS 布局问题(视口、安全区域和水平溢出)

如果内容在 iOS 上被裁切、偏移或水平滚动,请尝试 overflow-x: hidden 或仅仅调整视口标签通常无法解决问题。按照以下顺序检查这些问题。

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

App 路由 (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安全区域

创建一个单独的应用程序外壳并在那里应用安全区域填充 — 不在多个嵌套组件中:

将所有页面内容包装在

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-screenw-full 当可能时,很多水平溢出问题来自 100vw / w-screen,重复的安全区域填充,或者一个固定的宽度容器——而不是来自视口元标签本身。

性能优化

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

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

结论

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

您完成了以下工作:

  • 配置 Next.js 以静态导出
  • 添加 Capacitor 8 和必需插件
  • 在 iOS 和 Android 模拟器上构建和部署
  • 启用开发中的实时重载
  • 修复常见的 iOS 布局问题(视口、安全区域、溢出)
  • 添加原生感知的 UI 使用 Capgo 原生导航和过渡

下一步:

  • 设置 Capgo 为无线更新而设置
  • 添加更多本机插件,如摄像头、地理位置或推送通知
  • 配置应用程序图标和启动屏幕
  • 准备应用程序

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

Next.js 文档

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

从将您的 Next.js 应用程序转换为 iOS &amp; Android 的 Capacitor 8

如果您正在使用 将您的 Next.js 应用程序转换为 Capacitor iOS &amp; Android 为 native 插件工作做好准备,连接它 Capgo 插件目录 在 Capgo 插件目录中了解产品工作流程 Capacitor 插件由 Capgo 在 Capacitor 插件由 Capgo 中了解实现细节 添加或更新插件 在添加或更新插件中了解实现细节 Ionic 企业插件替代方案 在 Ionic 企业插件替代方案中了解产品工作流程 Capgo 原生构建 在 Capgo 原生构建中了解产品工作流程

Capacitor 应用的实时更新

当一个 web-layer 的 bug 是活跃的,通过 Capgo 将修复发送给用户,而不是等待几天的 app store 审核。用户在后台接收更新,而本机更改保持在正常的审查路径中。

来自 Martin 的人工支持

立即开始

最新的博客文章

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