Nuxt.jsのバージョンが2.13以上の方はこの記事を読み飛ばしてください。
今回達成すること
Nuxt.js v2.13が2020/6/19にリリースされました。
今回は、リリースに伴いDockerコンテナ上のNuxt.jsを2.13にバージョンアップします。
また、v2.13からの6つの新機能と2つの変更点、計8つのポイントについて解説していきます。
- クローラーの内臓【New】
- targetプロパティの追加【New】
- nuxt exportコマンドの追加【New】
- generateコマンドの非推奨
- 利用可能なコマンドの変更
- コンポーネントファイルの自動読み込み【New】
- RuntimeConfigの追加【New】
- Telemetryプロパティの追加【New】
それでは作業に入りましょう。
ブランチ切っとく
「front」ディレクトリ上の作業になりますので移動しておきましょう。
root $ cd front
大きな変更になるのでブランチを切ります。
front $ git checkout -b 20200717_nuxt_v2.13_versionup
front $ git branch
* 20200717_nuxt_v2.13_versionup
Nuxt.js v2.13バージョンアップ手順
バージョンアップはNuxt.js公式アップグレードガイドに従います。
1. package.jsonのバージョンを書き換える
nuxt
と、eslint
を最新のバージョンに書き換えます。
それに伴い、ESLintのスクリプトも変わりました。
package.jsonにはコメントが付けれません。下記コードはコピペしないでください。
front/package.json
{
"name": "app",
"version": "1.0.0",
"description": "My stunning Nuxt.js project",
"author": "andou",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .", // 削除
"lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .", // 追加
"lint": "yarn lint:js" // 追加
},
"dependencies": {
"nuxt": "^2.13.0", // v2.13.0に書き換え
"@nuxtjs/axios": "^5.3.6"
},
"devDependencies": {
"@nuxtjs/eslint-config": "^3.0.0", // v3.0.0に書き換え
"@nuxtjs/eslint-module": "^2.0.0", // v2.0.0に書き換え
"babel-eslint": "^10.1.0", // v10.1.0に書き換え
"eslint": "^7.2.0", // v7.2.0に書き換え
"eslint-plugin-nuxt": "^1.0.0" // v1.0.0に書き換え
}
}
^(キャレット)
... バージョン2のうち、2.13以上の最新のものを指定。
2. yarn.lockファイルを削除する
パッケージインストール後に自動で作られるので恐ることはありません。
front $ git rm yarn.lock
rm 'yarn.lock'
3. node_modulesディレクトリを削除
モジュールと夢が詰まった「node_modules」ディレクトリを削除します。
front $ rm -rf node_modules
-
rm
... ファイルを削除するLinuxコマンド。「node_modules」はGitの管理下ではないので
git rm
コマンドは使いません。 -
r
... 隠しファイルやサブディレクトリを含むディレクトリのコンテンツを削除する。 -
f
... 削除確認を省略する。
4. パッケージをインストールする
それではパッケージを再インストールします。
「root」ディレクトリ上で$ yarn install
を実行しましょう。
front $ cd ..
root $ docker-compose run --rm front yarn install
5. Nuxt.jsのバージョンを確認
バージョンは2.13上になっているか確認します。
root $ docker-compose run --rm front yarn list --pattern nuxt
...
└─ nuxt@2.13.3
OK!!
6. 実行を確認
無事バージョンアップできたかNuxt.jsを起動して確認してましょう。
root $ docker-compose up
http://localhost:8080/ にアクセスして前回と同じ表示だったらOKです。
確認が取れたらコンテナを削除します。
root $ 「control」+「C」
root $ docker-compose down
7. nuxt.config.jsをv2.13用に編集する
v2.13からの新機能を利用するために
下記3つのプロパティを追加します。
target: 'server'
components: true
publicRuntimeConfig: {}
変更後の
front/nuxt.config.js
export default {
mode: 'spa',
// 追加
// Doc: https://ja.nuxtjs.org/blog/going-full-static/
target: 'server',
head: {
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
loading: { color: '#fff' },
css: [
],
plugins: [
'plugins/axios'
],
// 追加
// Doc: https://nuxtjs.org/api/configuration-components
components: true,
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'@nuxtjs/eslint-module'
],
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios'
],
// 追加
// public ENV
// Doc: https://nuxtjs.org/guide/runtime-config/
publicRuntimeConfig: {},
axios: {
},
build: {
// 削除
// extend (config, ctx) {
// }
}
}
8. package.jsonに新コマンドを追加する
v2.13から追加されたexport
とserve
コマンドを書き足しましょう。
同時に非推奨(v3では削除予定)のgenerate
コマンドは削除します。
front/package.json
...
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"export": "nuxt export", // 追加
"serve": "nuxt serve", // 追加
"generate": "nuxt generate", // 削除
"lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lint": "yarn lint:js"
},
9. テレメトリーファイルをGitの管理外に
Docker環境のみ作成される
このファイルはテレメトリーのログファイルです。
front/.gitignore
# 追加
# Nuxt.js テレメトリーファイル
# Doc: https://nuxtjs.org/api/configuration-telemetry/
/.nuxtrc
以上でNuxt.js v2.13への完全な移行が完了しました。
Nuxt.js v2.13からの6つの新機能と2つの変更点
Nuxt.js v2.13からの6つの新機能が追加されました。
それに伴い2つの大きな変更がありました。
- クローラーの内臓【New】
- targetプロパティの追加【New】
- nuxt exportコマンドの追加【New】
- generateコマンドの非推奨
- 利用可能なコマンドの変更
- コンポーネントファイルの自動読み込み【New】
- RuntimeConfigの追加【New】
- Telemetryプロパティの追加【New】
1. 内部クローラーで動的ルーティングを自動生成
Nuxt.js v2.13からクローラーが内臓されました。
これにより動的ルーティングを自動生成してくれます。
v.2.12以前
下記のようなファイル構成のルーティングは手動で追加する必要がありました。
pages
└── posts
└── slug.vue
nuxt.config.js(v.2.12以前)
generate: {
routes: [
'/posts/test1',
'/posts/test2',
'/posts/test3'
]
}
実務的には$ yarn generate
コマンドの実行時にapiを取得し、そこから動的ルーティングを追加していました。
nuxt.config.js(v.2.12以前)
generate: {
fallback: true,
routes () {
const client = require('./plugins/contentful')
return Promise.all([
client.getEntries({ content_type: 'category' }),
client.getEntries({ content_type: 'blogPost' })
]).then(([categories, posts]) => {
return [
...categories.items.map((cat) => {
return { route: `categories/${cat.fields.slug}`, payload: cat }
}),
...posts.items.map((post) => {
return { route: `posts/${post.fields.slug}`, payload: post }
})
]
})
}
}
v.2.13以後
もう何もしなくて良いんです。
内部クローラーが自動で動的ルーティングを生成してくれます。
payloadは利用不可
クローラーによる動的ルーティングの自動生成は、payload
を使ってオブジェクトを取得しようとした場合、ビルド時にエラーを吐きます。
v.2.13からは使わないでください。
payloadの詳細 payloadによる動的ルーティング生成の高速化 - Nuxt.js
クローラーから一部のルートを除外する
クローラーから一部のルートを除外する場合はexclude
を使います。
nuxt.config.js
generate: {
exclude: [
/^\/admin/ // path starts with /admin
]
}
クローラーにルートを追加する
クローラーが検出できないルートについては、引き続きroutes()
を使用します。
nuxt.config.js
generate: {
routes () {
'posts/test4'
}
}
クローラーの無効化
クローラーを無効化することもできます。
nuxt.config.js
generate: {
crawler: false // クローラーの無効化
}
generateのエイリアスexportを追加
上記generate
プロパティはexport
に書き換えることができます。
双方ともNuxt.js v3で残る予定です。
2. targetプロパティの追加
target
プロパティが追加されました。
※ このオプションは主にUniversalモードで活用します。
nuxt.config.js
export default {
target: 'static' // (server || static)
}
2つの値が用意されています。
1. server(デフォルト)
サーバーサイドレンダリング用モード。
Nuxt.js v2.12以前のUniversal
モードと変わりない動きをする認識でOKです。
断言できず。情報少なし。
2. static
静的サイト用、事前レンダリングモード。
static
モードは、Nuxt.jsに静的HTMLファイルを出力するように伝えます。
Nuxt.jsアプリをあらかじめHTMLファイルに出力することで、超高速なアプリケーションを実現します。
サーバー側でレンダリングする理由がない限り、このモードをおすすめします。
ページ遷移が驚愕のスピードだった...。
SPAモードの場合はどっちにすれば良い?
結論から言うと、SPAモードの場合はtarget: 'server'
を指定します。
ユーザー認証型のアプリではstaticモードが使えない
まず前提として、今回のようなユーザー認証型のアプリでは、ユーザー名などの値が動的に変わるのでstatic
モードは使用できません。これは公式でも言われています。
例えば、コンテンツがユーザー認証やリアルタイムAPIに依存するアプリケーションには使用できません(少なくとも最初のロード時には)
serverモードはSPAモードでもサーバサイドレンダリングされるのか?
ただ、server
モードを使用すればサーバサイドレンダリングが行われるのでは?と疑問が残ります。
そこでサーバサイドレンダリング時にエラーを吐く、JavaScriptのwindow
オブジェクトを使ってHerokuにデプロイしてみました。
Nuxt.js SPAモード + target: 'server' でのHerokuデプロイ
画像の通り、エラーなくブラウザのウィンドウ幅を取得できました。
これはサーバ側でのレンダリングは行われていないと言うことです。
このことから、SPAモードではtarget: 'server'
を指定する方が適切だと判断しました。
間違った判断の場合ご指摘ください。早急に対応いたします。
2020年9月4日 追記 V2.14の仕様
V2.14になってコマンドの仕様が大きく変わりました。
Nuxt v2.13では、静的ターゲット用に特別に設計された
nuxt export
とnuxt serve
を導入しました。Nuxt v2.14 では、
nuxt generate
とnuxt start
がターゲットを検出して必要に応じてビルドするようになったため、これらは非推奨となりました。
Server target
-
nuxt dev
... 開発用サーバの起動。 -
nuxt build
= 本番用のアプリケーションをビルドする。 -
nuxt start
= 本番サーバを起動します 。(Heroku, Digital OceanなどのNode.jsホスティングに使用します)
Static target
nuxt dev
... 開発サーバの起動nuxt generate
= 必要に応じてビルドし、 dist/に静的にエクスポートします。nuxt start
... 静的なホスティング(Netlify, Vercel, Surge など)のように dist/ディレクトリを提供し、デプロイ前のテストに最適です。
3. nuxt exportコマンドの追加
staticモードの追加に伴い、新しいnuxt export
コマンドが追加されました。
Nuxt.jsアプリを「dist」ディレクトリに静的HTMLとしてエクスポートします。
※ このコマンドはstaticモードの場合に使用できます。
package.json
"scripts": {
"export": "nuxt export"
}
exportコマンドの注意点
このコマンドを実行する前は、必ずnuxt build
を実行しなければなりません。
コマンドで表すと下記の通りです。
$ yarn build && yarn export
4. generateコマンドの非推奨
export
コマンドの追加により、generate
コマンドが非推奨となりました。
Nuxt.js v2系では正常に動いていますが、将来のv3では削除されます。
5. targetによって変わる利用可能なコマンド
target
プロパティの値により利用できるコマンドが変わります。
server
nuxt dev
... 開発モードのサーバを起動する。nuxt build
... 本番環境用にビルド(webpackでのアプリ構築、JS・CSSを最小化)する。nuxt start
... 本番モードのサーバを起動する。
static
nuxt dev
... 開発環境用のサーバを起動する。nuxt build
... 本番環境用にビルドする。nuxt export
... すべてのルートをHTMLファイルとして「dist」ディレクトリに生成する。nuxt serve
... 本番モードのサーバを起動、「dist」ディレクトリの読み込み。
targetによって変わる本番環境のnuxtコマンド
target
の値によって本番環境のコマンドも変化します。
NetlifyとHerokuのケースをご紹介します。
Netlify + static の本番環境コマンド
ブログやホームページなどの静的サイトは、基本的にtarget: static
モードを使用しましょう。
Netlifyに登録するコマンドはこのようになります。
yarn build && yarn export
Netlify + server の本番環境コマンド
target: server
を指定した場合はgenerate
コマンドが必要です。
まず
package.json
"scripts": {
"generate": "nuxt generate"
},
Netlifyにはこのコマンドを登録します。
yarn build && yarn generate
generateコマンドはNuxt v3で削除されますが、これ以外のデプロイ方法は見つかりませんでした。
以上のことも含め
static
モードをおすすめします。
Heroku + server の本番環境コマンド
Nuxt.jsのSPAモードは基本的にserver
モードを使用します。
本番環境の起動コマンドはこのようになります。
yarn build && yarn start
Heroku + static の本番環境コマンド
static
モードで「start」コマンドは使えません。
本番環境の起動コマンドはこのようになります。
yarn build && yarn export && yarn serve
6. コンポーネントファイルの自動インポート
コンポーネントファイルが自動でインポートされるようになりました。
もう忌々しいimport
文は必要ありません。
v 2.12以前
コンポーネントを読み込むにはファイルをインポートしてcomponents
に登録する必要がありました。
vueファイル
<template>
<div>
<my-btn />
</div>
</template>
<script>
import myBtn from '~/components/ui/myBtn'
export default {
components: {
myBtn
}
}
</script>
v 2.13以後
components
プロパティが追加されました。
true
の場合は「components」ディレクトリ以下のファイルが自動で読み込まれるようになりました。
nuxt.config.js
components: true
もうimport
文とcomponents
への登録は必要ありません。
vueファイル
<template>
<div>
<my-btn />
</div>
</template>
<script>
export default {
}
</script>
推奨されるコンポーネントファイル名
呼び出しコンポーネント名はファイル名となります。
つまり、コンポーネント名が重複すると正しく読み取ることができません。
公式ではコンポーネント名にディレクトリ名を付けることが推奨されています。
コンポーネントファイルパス
components
└── ui
└── uiBtn.vue
vueファイル
<ui-btn />
数字が付くコンポーネントファイルの呼び出し
名前に数字が付いたコンポーネントファイルの場合。
components
└── ui
├── uiBtn1.vue
├── uiBtn2.vue
└── uiBtn3.vue
呼び出し名はui-btn-1
のように「-」で区切る必要があります。
vueファイル
<template>
<div>
<ui-btn-1 />
<ui-btn-2 />
<ui-btn-3 />
</div>
</template>
<script>
export default {
}
</script>
命名規則のカスタマイズ(prefixオプション)
呼び出しコンポーネント名はカスタマイズも可能です。
例えば「ui」ディレクトリのボタンをmy-btn
で呼び出したい場合はprefix
オプションを使います。
このオプションを使えば、同じファイル名のコンポーネントも正しく読み取ることができます。
nuxt.config.js
components: [
'~/components/', // その他のコンポーネントを呼び出し
{
path: "~/components/ui/",
prefix: "my"
}
],
コンポーネントファイルパス
components
├── btn.vue
└── ui
└── btn.vue
vueファイル
<template>
<div>
<btn />
<my-btn />
</div>
</template>
<script>
export default {
}
</script>
自動インポートの挙動が不安定な部分
components
プロパティのv 2.13.3時点で未対応、もしくは挙動が不安定な部分を頭に入れておきましょう。
新機能の情報しか出てこない今、実務でハマりやすいポイントです。
1. isプロパティは挙動が不安定
コンポーネントをis
プロパティで呼び出しできません。
ただし、同じコンポーネントを同じファイル内で呼び出せばis
プロパティも読み込まれます。
vueファイル
<template>
<div>
<!-- この場合はエラーとなる -->
<div is="ui-btn-1" />
<!-- こいつを読み込めばisプロパティも正常に読み込まれる -->
<!-- <ui-btn-1 /> -->
</div>
</template>
<script>
export default {
}
</script>
挙動が不安定なため、import
文を追加して対応しましょう。
vueファイル
<template>
<div is="ui-btn-1" />
</template>
<script>
import uiBtn1 from '~/components/ui/uiBtn1'
export default {
components: {
uiBtn1
}
}
</script>
2. 動的コンポーネントには未対応
v2.13.3時点で動的コンポーネントには未対応です。(公式ブログより)
こちらもimport
文で対応します。
vueファイル
<template>
<div>
<button
type="button"
name="button"
@click="isClick = !isClick"
>
コンポーネントを切り替える
</button>
<div :is="buttonComponent" />
</div>
</template>
<script>
import uiBtn1 from '~/components/ui/uiBtn1'
import uiBtn2 from '~/components/ui/uiBtn2'
export default {
components: {
uiBtn1,
uiBtn2
},
data () {
return {
isClick: false
}
},
computed: {
buttonComponent () {
return this.isClick ? 'ui-btn-2' : 'ui-btn-1'
}
}
}
</script>
7. RuntimeConfigの追加
環境変数を置く@nuxtjs/dotenv
モジュールのインストールが不要となりました。
nuxt.config.js
export default {
publicRuntimeConfig: {},
privateRuntimeConfig: {}
}
1. publicRuntimeConfig
ここに登録した環境変数は、サーバーとクライアントの両方で使用できます。
サイト名やサイトURLなどの公開用環境変数を保持します。
.env
BASE_NAME=サイト名
BASE_URL=http://localhost:8080
登録名はJavaScriptの命名規則(キャメルケース)に従います。
nuxt.config.js
publicRuntimeConfig: {
baseName: process.env.BASE_NAME,
baseUrl: process.env.BASE_URL
}
Vueファイルからの呼び出しは$config
で行います。
vueファイル
<template>
<div>
{{ $config.baseName }}
{{ $config.baseUrl }}
</div>
</template>
<script>
export default {
}
</script>
コンテキストからの呼び出しも$config
を使います。
vueファイル
<template>
<div>
{{ baseName }}
{{ baseUrl }}
</div>
</template>
<script>
export default {
asyncData ({ $config }) {
return {
baseName: $config.baseName,
baseUrl: $config.baseUrl
}
}
}
</script>
コンテキストにはこんな呼び出し方もあります。
vueファイル
export default {
asyncData ({ $config: { baseName, baseUrl } }) {
return { baseName, baseUrl }
}
}
2. privateRuntimeConfig
ここに登録した環境変数はサーバーでのみ使用できます。
主に公開すべきではない重要な環境変数を保持します。
nuxt.config.js
privateRuntimeConfig: {
apiKey: process.env.API_KEY
}
.envファイルに登録した環境変数は参照可能
privateRuntimeConfig
に登録しなくてもSSR時に参照できます。
vueファイル
export default {
created () {
console.log(process.env)
}
}
ターミナル
...
API_KEY: 'my-api-key',
BASE_NAME: 'サイト名'
}
となると、privateRuntimeConfig
はいつ使うんだ?と疑問が出ましたが、答えはまだ見つかっていません。
envプロパティは引き続き利用可能
今まで使っていたenv
プロパティは引き続き利用可能です。
ここには実行時ではなく、NODE_VERSION=1.1.1
のようなビルド時に必要な環境変数を登録します。
Contentfulで使用する環境変数
Contentfulで使用するspace_id
やaccess_token
はenv
プロパティに登録します。
nuxt.config.js
env: {
CTF_SPACE_ID: process.env.CTF_SPACE_ID,
CTF_CDA_ACCESS_TOKEN: process.env.CTF_CDA_ACCESS_TOKEN,
CTF_PREVIEW_API_KEY: process.env.CTF_PREVIEW_API_KEY
}
privateRuntimeConfig
に渡しても記事は取得できますが、フロントサイドでエラーが出ます。
env
プロパティを使えば良いと思います。
参考
8. Telemetryプロパティの追加
Nuxtアプリの使用情報を匿名で収集するtelemetry
が追加されました。
Nuxt.jsは下記の情報を収集します。
- 呼び出したコマンド(nuxt dev, nuxt build など)
- Nuxt.js と Node.js のバージョン
- 一般的なマシン情報 (MacOS/Linux/Windows、CI内でコマンドが実行されている場合はCI名)
- nuxt generate または nuxt export を使用している場合に、Webpack のビルド時間とアプリケーションの平均サイズ、および生成統計情報
- プロジェクトの依存関係(Nuxt モジュール)
Telemetryの有効・無効の確認
Telemetryが有効か無効かを確認するには環境変数にデバッグ変数を登録します。
.env
NUXT_TELEMETRY_DEBUG=1
無効の場合、Nuxt起動時に「無効である」と表示されるだけです。
ターミナル
$ yarn dev
...
ℹ Telemetry enabled
有効の場合、テレメトリーIDと、送信内容が表示されます。
ターミナル
$ yarn dev
...
ℹ Telemetry enabled
ℹ Seed generated: 6e9289cadf13cafc
...
ℹ Sending events: {
"timestamp": 1595141779681,
"context": {
"nuxtVersion": "2.13.3",
"isEdge": false,
"nodeVersion": "12.6.0",
"cli": "nuxt",
"os": "darwin",
"environment": "unknown",
"projectHash": "2230631a784f5b79",
"projectSession": "c026118c2e174004"
},
...
Telemetryを無効にする
無効にする場合はtelemetry
プロパティを追加します。
nuxt.config.js
telemetry: false
もしくは環境変数に下記値を設定します。
.env
NUXT_TELEMETRY_DISABLED=1
Telemetryを有効にする
有効にしたい場合はtelemetry
プロパティにtrue
を渡します。
nuxt.config.js
telemetry: true
以上でNuxt.js v2.13の新機能解説を終わります。
Herokuにpushする
「front」ディレクトリに移動してHerokuにpushしましょう。
root $ cd front
front $ git add -A
front $ git commit -m "updated_nuxt_v2.13.3"
front $ git checkout master
front $ git merge 20200717_nuxt_v2.13_versionup
front $ git push
front $ git push heroku
デプロイが終わったら、本番環境でも正しく動いていることを確認してください。
終わりに
いろいろ便利になった反面、また覚えることが増えましたね。とほほ。
Nuxt.js v2.13からの新機能は v3を見据えたバージョンアップとなっています。
早めに対応してNuxt.js v3 の公開に備えましょう。
次回は?
Nuxt.jsにVuetifyを導入します。
ただ今のDockerfileままでVuetifyをインストールするとエラーが出てます。
そのエラー対応についても解説していきます。
どうぞ下の記事リストへ(↓GO💨)
(コラム)target: staticでもSEO対策はできる?
これは筆者の壮大な勘違いの覚書きです。
筆者は当初「SEO対策するにはサーバーサイドレンダリングを行わなければならない」と思い込んでいました。
サーバーサイドレンダリングとは、Nuxt.jsのコードをサーバー側でHTMLファイルに変換することです。
Nuxt.js v2.12以前はこの考えで間違いありません。
しかしtarget
オプションが追加された今、SEO対策はどのように考えればいいでしょうか。
SEOに必要なのは?
そもそもクローラーは、サーバのHTMLファイルを読み取っています。
本質を考えると、SEO対策に必要なのは「サーバ側でのレンダリング」ではなく「サーバのHTMLファイル」と言うことです。
staticモードの動き
static
モードは、事前にコンパイルしたファイルを「dist」ディレクトリに吐き出します。
コンパイルとは、Nuxt.jsのコードを純粋なhtml/css/javascriptに変換することです。
つまり、サーバにはHTML・CSS・JavaScriptで構成されたファイルが存在するため、static
モードでもSEO対策は十分に可能と言うことです。
Twitterクローラーで試してみた
試しにTwitterクローラーが正しくOGPを読み取っているか確認してみました。
OGPとは
OGPとは、SNS上でWebサイトの情報を伝えるために定められた規約のことです。
OGPが読み込まれると、URLの内容を読み取ってカード形式等で表示されます。
検証判断
OGPの読み取りはサーバのHTMLファイルを参照します。
もしTwitterクローラーがOGPを正しく読み取った場合、サーバにHTMLファイルが存在することが証明されます。
検証結果
Nuxt.jsで構築したブログサイトにmeta
ダグを設定し、Netlifyにデプロイして実験しました。
結果、OGPは正しく読み取りできており記事の内容がTwitterに表示されました。
結論
Nuxt.jsのUniversal
モードでtarget: 'static'
を選択したときでもSEO対策は可能である。
(コラム終わり)