Next.js Native使ってみた

# Next.js Nativeってなんぞや❓
[Capacitor](https://capacitorjs.jp/docs) と呼ばれるwebアプリをクロスプラットフォーム化するライブラリを使って、
Next.jsをネイティブアプリ化できるようにしたものみたい👀

https://nextjs-native.com/

Githubにてスターターキットも用意されてたので、これを試す
https://github.com/RobSchilderr/nextjs-native-starter

とりあえず、Githubからクローン

```bash
$ git clone git@github.com:RobSchilderr/nextjs-native-starter.git
Cloning into 'nextjs-native-starter'...
remote: Enumerating objects: 3127, done.
remote: Counting objects: 100% (747/747), done.
remote: Compressing objects: 100% (406/406), done.
remote: Total 3127 (delta 382), reused 625 (delta 296), pack-reused 2380
Receiving objects: 100% (3127/3127), 3.59 MiB | 1.22 MiB/s, done.
Resolving deltas: 100% (1617/1617), done.
```

```bash
$ cd nextjs-native-starter
❯ npx create-supertokens-app@latest --manager=yarn
Need to install the following packages:
  create-supertokens-app@latest
Ok to proceed? (y) y

 _____                     _____     _
/  ___|                   |_   _|   | |
\ `--. _   _ _ __   ___ _ __| | ___ | | _____ _ __  ___
 `--. \ | | | '_ \ / _ \ '__| |/ _ \| |/ / _ \ '_ \/ __|
/\__/ / |_| | |_) |  __/ |  | | (_) |   <  __/ | | \__ \
\____/ \__,_| .__/ \___|_|  \_/\___/|_|\_\___|_| |_|___/
            | |
            |_|


create-supertokens-app (v0.0.40) lets you quickly get started with using SuperTokens!

Choose your tech stack and the authentication method, we will create a working project that uses SuperTokens for you.

? What is your app called? <自分のアプリ名を入力>
? Choose a frontend framework (Visit our documentation for integration with other frameworks): <Capacitor> を選択

✅ Finished setting up folder structure!

✅ Setup complete!


create-supertokens-app uses nextjs-native-starter as a template app for Capacitor. nextjs-native-starter is a starter project created by https://github.com/RobSchilderr, if you face any problems please open an issue here: https://github.com/RobSchilderr/nextjs-native-starter/issues or reach out to us on the SuperTokens Discord server: https://supertokens.com/discord.

To get started refer to the README on Github https://github.com/RobSchilderr/nextjs-native-starter
npm notice
npm notice New major version of npm available! 8.1.2 -> 10.2.4
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.4
npm notice Run npm install -g npm@10.2.4 to update!
npm notice
```


```bash
$ yarn install
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error lint-staged@13.3.0: The engine "node" is incompatible with this module. Expected version "^16.14.0 || >=18.0.0". Got "16.13.1"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
```

Node.jsのバージョンが若干古かったので、アップデートする。

```bash
$ node -v
v16.13.1
```

自分は `asdf` を利用してるので、取り急ぎローカルインストール

```bash
$ asdf install nodejs 20.10.0
nodejs 20.10.0 is already installed
$ asdf local nodejs 20.10.0
```

```bash
$ yarn install
yarn install v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
warning " > @testing-library/react@14.0.0" has unmet peer dependency "react@^18.0.0".
warning " > @testing-library/react@14.0.0" has unmet peer dependency "react-dom@^18.0.0".
warning " > @testing-library/react-hooks@8.0.1" has unmet peer dependency "react@^16.9.0 || ^17.0.0".
warning "@testing-library/react-hooks > react-error-boundary@3.1.4" has unmet peer dependency "react@>=16.13.1".
warning " > @testing-library/user-event@14.4.3" has unmet peer dependency "@testing-library/dom@>=7.21.4".
warning " > ts-node@10.9.1" has unmet peer dependency "@types/node@*".
warning "workspace-aggregator-eedda6f6-92a8-4dd2-b705-1ca1f11784ee > next-app > autoprefixer@10.4.15" has unmet peer dependency "postcss@^8.1.0".
warning "workspace-aggregator-eedda6f6-92a8-4dd2-b705-1ca1f11784ee > app > nextjs-cors@2.1.2" has incorrect peer dependency "next@^8.1.1-canary.54 || ^9.0.0 || ^10.0.0-0 || ^11.0.0 || ^12.0.0 || ^13.0.0".
warning "workspace-aggregator-eedda6f6-92a8-4dd2-b705-1ca1f11784ee > config > eslint-config-airbnb@19.0.4" has unmet peer dependency "eslint-plugin-jsx-a11y@^6.5.1".
warning "workspace-aggregator-eedda6f6-92a8-4dd2-b705-1ca1f11784ee > config > eslint-config-airbnb@19.0.4" has unmet peer dependency "eslint-plugin-react@^7.28.0".
warning "workspace-aggregator-eedda6f6-92a8-4dd2-b705-1ca1f11784ee > config > eslint-config-airbnb@19.0.4" has unmet peer dependency "eslint-plugin-react-hooks@^4.3.0".
warning "workspace-aggregator-eedda6f6-92a8-4dd2-b705-1ca1f11784ee > app > react-hot-toast > goober@2.1.13" has unmet peer dependency "csstype@^3.0.10".
[4/4] 🔨  Building fresh packages...
$ husky install
husky - Git hooks installed
✨  Done in 7.98s.
```

```bash
$ yarn dev
yarn run v1.22.19
$ turbo run dev --parallel
• Packages in scope: app, config, lib, next-app, next-web, tsconfig, ui
• Running dev in 7 packages
• Remote caching disabled
next-web:dev: cache bypass, force executing 3c76fff7a4831ea7
next-app:dev: cache bypass, force executing b13ac948800dc3f0
next-web:dev: $ next dev --port 3001
next-app:dev: $ next dev --hostname 0.0.0.0
next-app:dev:    ▲ Next.js 14.0.0
next-app:dev:    - Local:        http://localhost:3000
next-app:dev:    - Network:      http://0.0.0.0:3000
next-app:dev:
next-web:dev:    ▲ Next.js 14.0.0
next-web:dev:    - Local:        http://localhost:3001
next-web:dev:
next-app:dev:  ✓ Ready in 2.9s
next-web:dev:  ✓ Ready in 2.9s
next-app:dev:  ○ Compiling /page ...
next-app:dev:  ✓ Compiled /page in 2.5s (811 modules)
next-app:dev: Warning: Container: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.
next-app:dev:     at Container (webpack-internal:///(ssr)/../../packages/ui/components/Container.tsx:10:22)
next-app:dev:     at Hero
next-app:dev:     at main
next-app:dev:     at HomePage (webpack-internal:///(ssr)/./src/app/page.tsx:25:78)
next-app:dev:     at StaticGenerationSearchParamsBailoutProvider (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/static-generation-searchparams-bailout-provider.js:15:11)
next-app:dev:     at Lazy
next-app:dev:     at InnerLayoutRouter (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/layout-router.js:240:11)
next-app:dev:     at RedirectErrorBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/redirect-boundary.js:71:9)
next-app:dev:     at RedirectBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/redirect-boundary.js:79:11)
next-app:dev:     at NotFoundErrorBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/not-found-boundary.js:54:9)
next-app:dev:     at NotFoundBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/not-found-boundary.js:62:11)
next-app:dev:     at LoadingBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/layout-router.js:336:11)
next-app:dev:     at ErrorBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/error-boundary.js:128:11)
next-app:dev:     at InnerScrollAndFocusHandler (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/layout-router.js:152:9)
next-app:dev:     at ScrollAndFocusHandler (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/layout-router.js:227:11)
next-app:dev:     at RenderFromTemplateContext (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/render-from-template-context.js:15:44)
next-app:dev:     at Lazy
next-app:dev:     at OuterLayoutRouter (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/layout-router.js:345:11)
next-app:dev:     at Lazy
next-app:dev:     at main
next-app:dev:     at body
next-app:dev:     at SessionAuth (webpack-internal:///(ssr)/../../node_modules/supertokens-auth-react/lib/build/index2.js:857:23)
next-app:dev:     at UserContextProvider (webpack-internal:///(ssr)/../../node_modules/supertokens-auth-react/lib/build/index2.js:69:23)
next-app:dev:     at UserContextWrapper (webpack-internal:///(ssr)/../../node_modules/supertokens-auth-react/lib/build/index2.js:820:15)
next-app:dev:     at SessionAuthWrapper (webpack-internal:///(ssr)/../../node_modules/supertokens-auth-react/lib/build/index2.js:1243:34)
next-app:dev:     at SuperTokensWrapper
next-app:dev:     at SuperTokensProvider (webpack-internal:///(ssr)/./src/app/ui/supertokensProvider.tsx:22:32)
next-app:dev:     at Lazy
next-app:dev:     at html
next-app:dev:     at RedirectErrorBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/redirect-boundary.js:71:9)
next-app:dev:     at RedirectBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/redirect-boundary.js:79:11)
next-app:dev:     at ReactDevOverlay (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:66:9)
next-app:dev:     at HotReload (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:298:11)
next-app:dev:     at Router (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/app-router.js:154:11)
next-app:dev:     at ErrorBoundaryHandler (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/error-boundary.js:99:9)
next-app:dev:     at ErrorBoundary (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/error-boundary.js:128:11)
next-app:dev:     at AppRouter (webpack-internal:///(ssr)/../../node_modules/next/dist/client/components/app-router.js:426:13)
next-app:dev:     at Lazy
next-app:dev:     at Lazy
next-app:dev:     at /Users/t00944/work/nextjs-native-starter/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:374733
next-app:dev:     at /Users/t00944/work/nextjs-native-starter/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:374733
next-app:dev:     at ServerInsertedHTMLProvider (/Users/t00944/work/nextjs-native-starter/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:38:23140)
next-app:dev:  ✓ Compiled in 359ms (404 modules)
next-web:dev:  ○ Compiling /page ...
next-web:dev:  ✓ Compiled /page in 2.3s (757 modules)
```

ここで、実行ログに記載されてる `http://localhost:3000` にアクセスすると、以下のような画面が表示される。
これがおそらくPC版？

![その1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14268/85bdcf49-40b6-3e3b-88c7-f23c68d26caa.png)


ここからは `nextjs-native-starter` リポジトリのREADMEの[HOW TO USE](https://github.com/RobSchilderr/nextjs-native-starter#how-to-use)を参照しながらやった

## iOS
```
For iOS: go to the `next-app` folder and run `pnpm build` and `pnpm open:ios`.
```
とあるので、 `pnpm` -> `yarn` に置き換えて実行

```
$ yarn build
yarn run v1.22.19
$ next build && npx cap sync ios && npx cap sync android
   ▲ Next.js 14.0.0

 ✓ Creating an optimized production build
 ✓ Compiled successfully

./src/app/page.tsx
40:6  Warning: React Hook useEffect has a missing dependency: 'router'. Either include it or remove the dependency array.  react-hooks/exhaustive-deps

info  - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
 ✓ Linting and checking validity of types
 ✓ Collecting page data
   Generating static pages (0/9)  [    ] ⚠ Entire page /auth/callback/google deopted into client-side rendering. https://nextjs.org/docs/messages/deopted-into-client-rendering /auth/callback/google
   Generating static pages (5/9)  [=   ]
 ⚠ Entire page /auth/callback/apple deopted into client-side rendering. https:/
 ✓ Generating static pages (9/9)
 ✓ Finalizing page optimization

Route (app)                              Size     First Load JS
┌ ○ /                                    2.37 kB         108 kB
├ ○ /_not-found                          874 B          88.8 kB
├ ○ /auth/callback/apple                 2.07 kB         227 kB
├ ○ /auth/callback/google                2.07 kB         227 kB
├ ○ /login                               188 B           251 kB
├ ○ /login-result                        2.54 kB         228 kB
└ ○ /register                            16.9 kB         268 kB
+ First Load JS shared by all            87.9 kB
  ├ chunks/1dd3208c-59a38ab4f4d458ab.js  53.3 kB
  ├ chunks/53-ea01855999212081.js        32.5 kB
  ├ chunks/main-app-9ad46d6a8ca641ae.js  230 B
  └ chunks/webpack-5bf40e569296600d.js   1.9 kB


○  (Static)  prerendered as static HTML

[warn] The bundledWebRuntime configuration option has been deprecated. Can be
       safely deleted.
✔ Copying web assets from out to ios/App/App/public in 17.28ms
✔ Creating capacitor.config.json in ios/App/App in 617.58μs
✔ copy ios in 24.00ms
✔ Updating iOS plugins in 649.75μs
[info] Found 3 Capacitor plugins for ios:
       @capacitor/app@5.0.6
       @capacitor/preferences@5.0.6
       @capacitor/splash-screen@5.0.6
✔ Updating iOS native dependencies with pod install in 21.43s
✔ update ios in 21.46s
[info] Sync finished in 23.354s
[?] Would you like to help improve Capacitor by sharing anonymous usage data? 💖
    Read more about what is being collected and why here:
    https://capacitorjs.com/telemetry. You can change your mind at any time by
    using the npx cap telemetry command.
✔ Share anonymous usage data? … yes

Thank you for helping to make Capacitor better! 💖
Information about the data we collect is available on our website: https://capacitorjs.com/telemetry
[warn] The bundledWebRuntime configuration option has been deprecated. Can be
       safely deleted.
✔ Copying web assets from out to android/app/src/main/assets/public in 24.70ms
✔ Creating capacitor.config.json in android/app/src/main/assets in 750.17μs
✔ copy android in 30.07ms
✔ Updating Android plugins in 757.29μs
[info] Found 3 Capacitor plugins for android:
       @capacitor/app@5.0.6
       @capacitor/preferences@5.0.6
       @capacitor/splash-screen@5.0.6
✔ update android in 23.71ms
[info] Sync finished in 0.056s
✨  Done in 25.25s.
```

ビルドが終わったようなので、 `yarn open:ios` を実行
```
$ yarn open:ios
yarn run v1.22.19
$ npx cap sync ios && npx cap open ios
[warn] The bundledWebRuntime configuration option has been deprecated. Can be
       safely deleted.
✔ Copying web assets from out to ios/App/App/public in 38.04ms
✔ Creating capacitor.config.json in ios/App/App in 746.13μs
✔ copy ios in 44.72ms
✔ Updating iOS plugins in 578.29μs
[info] Found 3 Capacitor plugins for ios:
       @capacitor/app@5.0.6
       @capacitor/preferences@5.0.6
       @capacitor/splash-screen@5.0.6
✔ Updating iOS native dependencies with pod install in 5.60s
✔ update ios in 5.63s
[info] Sync finished in 6.93s
✔ Opening the Xcode workspace... in 3.01s
✨  Done in 11.91s.
```

すると、Xcodeが起動するので、 `Run` を実行すると、シミュレータが起動して、以下のような画面が表示される。

![その2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14268/f1d7659d-9606-f2ff-643a-5ebcce49abb5.png)


PC版で作成したGoogleアカウントでログインしてみると、

![その4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14268/4c325fad-aba0-e4d3-d163-270e9eed9b6d.png)

## Android
```
for Android: go to the `next-app` folder and run `pnpm build` and `pnpm open:android`
```
とあるので、 `pnpm` -> `yarn` に置き換えて実行
すでに `yarn build` でビルドしてるので、 `yarn open:android` を実行

AndroidStudioが開くところまではきたけど、、、、構成追加とかして実行してもなんか動かずでした💦😭

![その3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14268/905a19da-315c-963c-4b88-b4ad8dd9d3eb.png)

# まとめ
- React Nativeっぽい感じで、Next.jsを使ってる感じはわかった
- [SuperTokens, Open Source Authentication](https://supertokens.com/)という認証ライブラリを使ってる
- [Capacitor](https://capacitorjs.jp/)を利用してNext.jsで作ったアプリをネイティブで動作するようにしてるみたい
- 今回は、iOSのみ動作確認できた