Nuxt.jsでサーバーサイドレンダリングを使用する方法
著者は、 Write for DOnations プログラムの一環として、 Open Sourcing MentalIllnessを選択して寄付を受け取りました。
序章
シングルページアプリケーション(SPA)は、シングルとしてレンダリングするアプリケーションです。 index.html
クライアント側のページ。 従来、SPAにはロード時にHTMLがほとんど含まれていませんでした。 代わりに、 Vue.js のようなフレームワークを使用すると、特定の条件が満たされたときにJavaScriptを介してコンテンツをHTMLラッパーに挿入できます。 これにより、動的でカスタマイズ可能なアプリケーションが作成されますが、検索エンジン最適化(SEO)の問題も発生します。これは、Webクローラーはサーバーからのファイルしか分析できず、動的に生成されたルート上の重要なHTMLはすべて分析されたことはありません。
Nuxt.js は、サーバー側レンダリングでこの問題を解決できるVue.jsアプリケーションのフレームワークです。これは、サーバー上でアプリケーションをレンダリングしてからクライアントに送信する戦略です。 Nuxtを使用すると、すべてのルートが .vue
内のファイル pages
ディレクトリ。 これらのページ内で、REST APIからデータをフェッチし、それを template
あなたのコンポーネントの。 内部のすべてのデータとHTML template
Nuxtサーバーによってレンダリングされます。Nuxtサーバーは生成されたものを送信します .html
クライアントにファイルします。 それ以来 .html
サーバーによって提供されるため、Webクローラーは任意のルートで重要なHTMLをすべて分析できます。
このチュートリアルでは、空港に関する情報を含むサンプルWebアプリケーションをセットアップします。 このアプリは、 About ページと、データセット内の空港ごとに動的に生成されたページを提供します。 次に、Nuxt.jsを使用して、ページルートを生成し、レイアウトコンポーネントを作成し、ページ固有のメタデータを設定します。
前提条件
- コンピューターにインストールされているNode.jsバージョン16.14.0以降。 これをmacOSまたはUbuntu20.04にインストールするには、Node.jsをインストールしてローカル開発環境を作成する方法またはNode.jsのインストール方法のPPAを使用したインストール」の手順に従います。 Ubuntu20.04で。
- また、JavaScript、HTML、およびCSSの基本的な知識も必要です。これは、 HTMLを使用してWebサイトを構築する方法シリーズ、CSSを使用してWebサイトを構築する方法シリーズにあります。 、およびJavaScriptでコーディングする方法。
ステップ1—サンプルアプリケーションにNuxtをインストールする
このステップでは、コンピューターの端末のコマンドを使用してNuxtプロジェクトを作成します。 このnpxコマンドは、プロンプトで指定した情報に従って新しいVue.jsプロジェクトを生成する外部スクリプトを実行します。 これは、VueCLIを使用して新しいVueプロジェクトを生成するときのvuecreateコマンドに似ています。 次に、サンプルアプリケーションをセットアップします。これを使用して、チュートリアルの後半でNuxt機能をテストします。
ターミナルで、次を実行します npx
指図。 このコマンドは、現在作業しているディレクトリにプロジェクトを生成します。
- npx create-nuxt-app favorite-airports
初めてのランニングの場合 create-nuxt-app
、最初にインストールする必要のあるパッケージのリストを示すプロンプトが表示されます。 タイプ y
とヒット ENTER
続ける:
OutputNeed to install the following packages:
create-nuxt-app
Ok to proceed? (y) y
必要なパッケージがインストールされると、最初のプロンプトが表示されます。
Outputcreate-nuxt-app v4.0.0
✨ Generating Nuxt.js project in favorite-airports
? Project name: (favorite-airports)
アプリの名前を入力するか、を押します ENTER
デフォルトを選択します。 次のブロックで強調表示されているオプションを選択して、プロンプトを個別に処理し続けます。
Output✨ Generating Nuxt.js project in favorite-airports
? Project name: favorite-airports
? Programming language: JavaScript
? Package manager: Npm
? UI framework: None
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: None
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: None
? What is your Github username?
? Version control system: Git
それが完了したら、ディレクトリを次のように変更します favorite-airports
ローカル開発サーバーを起動します。
- cd favorite-airports
- npm run dev
これにより、指定されたアドレスでアクセスできるローカルサーバーが起動します。 ブラウザで、 http://localhost:3000/
. 次のように表示されます。
プロジェクトが実行されているので、このチュートリアルでデータとして使用するオブジェクトの配列を追加することで、サンプルアプリをセットアップできます。
ターミナルを開き、プロジェクトのルートディレクトリで次のコマンドを実行します(favorite-airports
):
- mkdir data
これにより、 data
ディレクトリ。 選択したテキストエディタで、という名前のファイルを作成して開きます airports.js
の中に data
ディレクトリを作成し、以下を追加します。
export default [
{
name: 'Cincinnati/Northern Kentucky International Airport',
abbreviation: 'CVG',
city: 'Hebron',
state: 'KY'
},
{
name: 'Seattle-Tacoma International Airport',
abbreviation: 'SEA',
city: 'Seattle',
state: 'WA'
},
{
name: 'Minneapolis-Saint Paul International Airport',
abbreviation: 'MSP',
city: 'Bloomington',
state: 'MN'
},
{
name: 'Louis Armstrong New Orleans International Airport',
abbreviation: 'MSY',
city: 'New Orleans',
state: 'LA'
},
{
name: 'Chicago O\'hare International Airport',
abbreviation: 'ORD',
city: 'Chicago',
state: 'IL'
},
{
name: 'Miami International Airport',
abbreviation: 'MIA',
city: 'Miami',
state: 'FL'
}
]
これは、米国内のいくつかの空港で構成されるオブジェクトの配列です。 このデータを使用して、アプリのページを動的に生成します。
このファイルを保存して閉じます。
次に、CSSフレームワーク Taiwind をインポートして、アプリケーションにスタイルを追加します。 これを行うには、Nuxt構成ファイルを開きます nuxt.config.js
エディタで、次の強調表示されたコードを追加します。
export default {
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'favorite-airports',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'stylesheet', type: 'text/css', href: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css' }
]
},
...
}
構成ファイルを保存して閉じます。
これで、Nuxtがインストールされ、プロジェクトが生成され、Nuxt機能を試すように設定されました。 次のステップでは、配置することでさまざまなタイプのルートを自動的に作成します .vue
内のファイル pages
ディレクトリ。
ステップ2—経由でルートを生成する pages
ディレクトリ
従来のVue.jsアプリとは異なり、Nuxtのルートはルーターファイルを介して生成されません。 代わりに、それらはから生成されます pages
ディレクトリ。 各 .vue
このディレクトリ内のファイルはルートを生成します。 このステップでは、 About ページを作成し、空港ごとに動的にページを生成することで、この機能を試してみます。
あなたを見てください pages
ディレクトリ。 そこにはすでにページがあります: index.vue
. これは、静的なものを持つことと同等です index.html
ページ。 これ index.vue
ページには単一が含まれています <Tutorial />
ローカル開発サーバーを実行したときにブラウザーでレンダリングされたHTMLを保持するコンポーネント。 これは次のように表示されます。
<template>
<Tutorial />
</template>
<script>
export default {
name: 'IndexPage'
}
</script>
次に、独自の静的Nuxtルートを作成して、これを拡張します。 ターミナルで、というファイルを作成して開きます about.vue
Pagesディレクトリにあります。 拡張子の前のファイル名はURLパスになるため、この場合のURLは次のようになります。 your_site/about
. この中 about.vue
ファイルに、以下を追加します。
<template>
<div class="container mx-auto my-5">
<h1 class="text-2xl leading-7 font-semibold">This is the About Page</h1>
<p>This page contains the about information of this application. This is a static route created by Nuxt via the `about.vue` file in the pages directory</p>
</div>
</template>
<script>
export default {
name: 'AboutPage'
}
</script>
このページでは、 <h1>
ヘッダーと <p>
内の要素 <div>
. 次に、Tailwindクラスを使用して各要素にスタイルを追加し、フォントとマージンを設定しました。 の中に <script>
要素、追加しました name
Vueアプリでこのページを識別するためのプロパティ。
このファイルを保存して、 http://localhost:3000/about
. 作成したHTMLがブラウザに表示されます。
静的ルートを作成したので、動的ルートの作成に進むことができます。 このルートには、後で活用できるパラメータが含まれます。 .vue
ファイル。 URL構造は次のようになります /airport/:code
、 と :code
データセットの空港コードに置き換えられました。
Vue Router では、routes配列に次のようなオブジェクトが含まれている可能性があります。
const routes = [
{ path: '/airport/:code', component: AirportDetail }
]
しかし、前に示したように、Nuxtのルートは pages
ディレクトリ。 動的ルートを作成するには、 .vue
ファイルはアンダースコアで始まる必要があります(_
). アンダースコアに続くファイルの名前がパラメータ名になります。 これはに匹敵します :code
の /airports/:code
.
ターミナルで、という名前の新しいディレクトリを作成します airport
下 pages
:
- mkdir pages/airport
の中に airport
ディレクトリ、という名前のファイルを作成します _code.vue
テキストエディタで、以下を追加します。
<template>
<div class="container mx-auto my-5">
<h1 class="text-2xl leading-7 font-semibold">This is the Airport Detail Page</h1>
<p>This page contains the specific information about an airport.</p>
</div>
</template>
<script>
export default {
name: 'AirportDetailPage'
}
</script>
このファイルでは、スタイルを追加しています <h1>
と <p>
もう一度ページに移動しますが、今回は空港に固有のプレースホルダー情報が含まれています。 ファイルを保存して閉じます。
ブラウザを開いて http://localhost:3000/airport/cvg
そして、あなたは以下を見つけるでしょう:
このページを作成すると、次の場所でデータをフェッチできるようになります。 airport.abbreviation
プロパティは、 code
あなたのパラメータ pages
ディレクトリ。 Nuxtには、ここに関連する2つの追加のフックまたはライフサイクルメソッドがあります。 fetch
と asyncData
. あなたは使用することができます fetch
ページがレンダリングされる前にネットワーク呼び出しを行うメソッド。 The asyncData
このメソッドは、ページがレンダリングされる前にリアクティブデータをシェーピングするときに使用されます。
内部にあるリアクティブデータ asyncData
にマージされます data
そのページで。 例として、次のコードを取り上げます。
export default {
data() {
return {
lastName: 'Grohl'
}
},
asyncData() {
const firstName = 'Dave'
}
}
これは、次のように書くのと同じです。
export default {
data() {
return {
firstName: 'Dave',
lastName: 'Grohl'
}
},
}
唯一の違いは asyncData
サーバー上でレンダリングされますが、 data
クライアントでレンダリングされます。
試してみる asyncData
、からオブジェクトを返すfilterループを作成します。 airports.js
データセット:
...
<script>
import airports from '~/data/airports.js'
export default {
name: 'AirportDetailPage',
asyncData ({ route }) {
const airport = airports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
return {
airport
}
}
}
</script>
このコードでは、 airports.js
データをページに入力し、次の場所を除くすべてのオブジェクトを除外します。 abbreviation
と route.params.code
マッチ。 これはで行われるので asyncData
針、 airport
で使用できるデータプロパティになりました template
.
データを使用するには、次の強調表示された行をに追加します template
同じファイルのセクション:
<template>
<div class="container mx-auto my-5">
<h1 class="text-2xl leading-7 font-semibold">This is the Airport Detail Page</h1>
<p>This page contains the specific information about the <strong>{{ airport.abbreviation }}</strong> airport.</p>
</div>
</template>
...
このファイルを保存して、空港の略語を動的にレンダリングします。 ブラウザウィンドウを開いた場合 http://localhost:3000/airport/cvg
、テンプレートに空港コードが表示されます。 次のような別のコードで空港ルートにアクセスしてみてください /airport/sea
そのデータが更新されたことを確認します。
Nuxtで静的ルートと動的ルートを作成したので、これらのデータプロパティの表示に進むことができます airports.js
オブジェクト。 次のセクションでは、を作成します layouts
Nuxtで、それらをページに割り当てます。 それが完了したら、このステップで行ったことを活用して、より有用なデータをレイアウトに追加します。
ステップ3—Nuxtレイアウトの作成
Nuxtでは、ページのレイアウトを作成して、アプリケーションをよりモジュール化することができます。 これは、従来のVue.jsアプリでレイアウトコンポーネントを作成するプロセスと似ていますが、Nuxtでは、 layout
ページレベルのプロパティ。 このステップでは、動的に生成された空港の詳細ページごとに再利用するレイアウトを作成します。
レイアウトを作成するには、最初に layouts
プロジェクト内のディレクトリ:
- mkdir layouts
名前の付いたファイルを作成して開きます AirportDetail.vue
このディレクトリにあります。 このレイアウトでは、空港に関する情報を含むサイドバーが自動的に追加されます。 これを行うには、次のコードをファイルに追加します。
<template>
<div>
<Nuxt />
</div>
</template>
<script>
import airports from '~/data/airports.js'
export default {
computed: {
airport() {
return airports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
}
}
}
</script>
このコードでは、 airports.js
レイアウトにファイルを追加し、 computed
を介して空港オブジェクトを取得するプロパティ code
ルータのパラメータ。 The <Nuxt />
テンプレートの要素は、ページのコンテンツが挿入される場所です。 これはVueスロットと同様に機能します。
次に、いくつかのTailwindクラスを活用します。 以下を追加して、レイアウトとスタイルを設定します。
<template>
<div class="container mx-auto grid grid-cols-9 mt-5 gap-5">
<aside class="col-span-2">
<!-- sidebar -->
</aside>
<main class="col-span-7">
<!-- main content -->
<Nuxt />
</main>
</div>
</template>
...
このスニペットでは、すべてをにラップしています container
これも3列幅です grid
. The aside
要素はサイドバーであり、 main
要素はあなたのメインコンテンツです。
このグリッドを作成したら、いくつかのTailwindクラスを含むサイドバーを追加します。
<template>
<div class="container mx-auto grid grid-cols-9 mt-5 gap-5">
<aside class="col-span-2">
<!-- sidebar -->
<div class="shadow-md shadow-black mt-5 border p-5 rounded">
</div>
</aside>
<main class="col-span-7">
<!-- main content -->
<Nuxt />
</main>
</div>
</template>
...
これにより、 box-shadow、border、border-radius、 padding、margin-topなどのいくつかのスタイルが追加されます。 このサイドバーの内側に、いくつかの情報を入力します。
<template>
<div class="container mx-auto grid grid-cols-9 mt-5 gap-5">
<aside class="col-span-2">
<!-- sidebar -->
<div class="shadow-md shadow-black mt-5 border p-5 rounded text-center">
<p class="text-3xl font-bold">{{ airport.abbreviation }}</p>
<p>An airport located in {{ airport.city }}, {{ airport.state }}</p>
</div>
</aside>
<main class="col-span-7">
<!-- main content -->
<Nuxt />
</main>
</div>
</template>
...
このコードは、空港固有の詳細をページに追加し、テキストを中央に配置します。
先に進む前に、 <h1>
とともに airport.name
その値として。 これは上になります <Nuxt />
要素、このレイアウトですべてのページに表示されるため:
<template>
<div class="container mx-auto grid grid-cols-9 mt-5 gap-5">
<aside>...</aside>
<main class="col-span-7">
<!-- main content -->
<h1 class="text-3xl font-bold mt-5">{{ airport.name }}</h1>
<Nuxt />
</main>
<div>
</template>
...
これで、完全なレイアウトができました AirportDetail
ページ。 レイアウトファイルを保存して閉じます。
このレイアウトを使用するには、次に、 layout: AirportDetail
使用するページのプロパティ。 開く pages/airport/_code.vue
テキストエディタで、次の強調表示された行を追加します。
...
<script>
import airports from '~/data/airports.js'
export default {
name: 'AirportDetailPage',
asyncData ({ route }) {
const airport = airports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
return {
airport
}
},
layout: 'AirportDetail'
}
</script>
これが完了したら、このファイルを保存してブラウザを開き、 http://localhost:3000/airport/cvg
. これで、次のことがわかります。
注:ホットリロードは、この変更を常に自動的に実装するとは限りません。 ブラウザでレイアウトがレンダリングされない場合は、次のコマンドで開発サーバーを停止します。 CTRL
+C
、次に実行します npm run dev
サーバーを再起動します。
これが完了すると、適切な空港コードを使用してルートにアクセスすると、サイドバーに情報が自動的に表示されます。
このステップでは、レイアウトを作成してページに割り当て、アプリをDRYのままにしておくことができます。 次に、 context
ページ固有のプロパティを提供するオブジェクト。
ステップ4—サーバーの使用 context
ページ固有のプロパティ
Nuxtアプリケーションはサーバー上でレンダリングされるため、ページへのアクセス方法が明確でない場合があります。 route
, params
、さらにはVuexストア。 経由でVueインスタンス全体にアクセスできないため this
サーバー側では、Nuxtは context
のこれらのさまざまなプロパティに使用できるオブジェクト fetch
と asyncData
フック。 このステップでは、 context
空港のページに動的なページの説明を追加します。
このチュートリアルの前のセクションでは、すでに context
のオブジェクト _code.vue
ファイル:
<script>
export default {
asyncData ({ route }) {
const airport = airports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
return {
airport
}
},
layout: 'AirportDetail'
}
</script>
ここであなたは解体しました route
からのプロパティ context
それがあなたが必要とした唯一のプロパティだったので、オブジェクト。 ただし、次のような標準的な名前を付けることもできます。 context
また ctx
:
<script>
export default {
asyncData (context) {
const airport = airports.filter(airport => airport.abbreviation === context.route.params.code.toUpperCase())[0]
return {
airport
}
},
layout: 'AirportDetail'
}
</script>
に加えて context
オブジェクト、 fetch
メソッド、および asyncData
メソッドでは、ページには、ページレベルでのみアクセスできる追加のプロパティもあります。特に、 head
財産。 このプロパティを使用すると、注入することができます meta
に情報を <head>
ページがレンダリングされるときのDOM(ドキュメントオブジェクトモデル)の。 このプロパティの情報は、Webサーバーで読み取ることができます。
を設定するには description
あなたのページの、 _code.vue
テキストエディタのファイル:
<script>
export default {
...,
head() {
return {
title: 'Airport Information | Aiport App',
meta: [
{
hid: 'description',
name: 'description',
content: 'Detailed information about the specific airport.'
}
]
}
}
}
</script>
このコードでは、 head
オブジェクトを返す関数です。 追加しました title
このオブジェクトのプロパティと meta
を定義するオブジェクトの配列を持つプロパティ description
財産。 これは、静的に次のように書くのと同じです .html
ページ:
<head>
<title>Airport Information | Aiport App</title>
<meta hid="description" name="description" content="Detailed information about the specific airport.">
</head>
あなたの _code.vue
ファイルを作成し、ブラウザで開きます。 レンダリングされたDOMには、追加した情報が含まれます。
あなたはまた作ることができます title
と description
文字列補間を使用して現在の空港情報を <head>
エレメント:
<script>
export default {
head () {
return {
title: `${this.airport.name} Information | Aiport App`,
meta: [
{
hid: 'description',
name: 'description',
content: `Detailed information about the ${this.airport.name} (${this.airport.abbreviation}) airport.`
}
]
}
}
}
</script>
これで、ブラウザウィンドウを保存して更新すると、空港固有の情報が <head>
、これはアプリケーションの検索エンジン最適化(SEO)に役立ちます。
結論
このチュートリアルで説明されているように、Nuxtは、サーバー側でページを動的にレンダリングし、SEOを構成するためのツールを提供します。 <head>
プロパティを使用して、コードをモジュール化します。 layout
財産。 また、サーバー上でレンダリングされるデータを次のように定義することもできます。 asyncData
と fetch
、またはクライアントで data
.
Nuxtの機能の詳細については、公式Nuxtドキュメントにアクセスしてください。 Vueのその他のチュートリアルについては、Vue.jsシリーズページを使用してWebサイトを開発する方法を確認してください。