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を使用すると、すべてのルートがpages
ディレクトリの.vue
ファイルから生成されます。 これらのページ内で、REST APIからデータをフェッチし、それをコンポーネントのtemplate
に挿入できます。 template
内のすべてのデータとHTMLは、生成された.html
ファイルをクライアントに送信するNuxtサーバーによってレンダリングされます。 その.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
ディレクトリが作成されます。 選択したテキストエディタで、data
ディレクトリにairports.js
という名前のファイルを作成して開き、次のファイルを追加します。
お気に入り-airports/data / airports.js
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
を開き、次の強調表示されたコードを追加します。
お気に入り-airports/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機能を試すように設定されました。 次のステップでは、pages
ディレクトリ内に.vue
ファイルを配置することにより、さまざまなタイプのルートを自動的に作成します。
ステップ2—pages
ディレクトリを介したルートの生成
従来のVue.jsアプリとは異なり、Nuxtのルートはルーターファイルを介して生成されません。 代わりに、pages
ディレクトリから生成されます。 このディレクトリ内の各.vue
ファイルはルートを生成します。 このステップでは、 About ページを作成し、空港ごとに動的にページを生成することで、この機能を試してみます。
pages
ディレクトリを見てください。 そこにはすでにindex.vue
というページがあります。 これは、静的なindex.html
ページを持つことと同じです。 このindex.vue
ページには、ローカル開発サーバーを実行したときにブラウザーでレンダリングされたHTMLを保持する単一の<Tutorial />
コンポーネントが含まれています。 これは次のように表示されます。
お気に入り-airports/pages / index.vue
<template> <Tutorial /> </template> <script> export default { name: 'IndexPage' } </script>
次に、独自の静的Nuxtルートを作成して、これを拡張します。 ターミナルで、pagesディレクトリにabout.vue
というファイルを作成して開きます。 拡張子の前のファイル名はURLパスになるため、この場合のURLはyour_site/about
になります。 このabout.vue
ファイル内に、以下を追加します。
お気に入り-airports/pages / 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>
このページでは、<div>
内に<h1>
ヘッダーと<p>
要素を作成しました。 次に、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
ファイルがアンダースコア(_
)で始まる必要があります。 アンダースコアに続くファイルの名前がパラメータ名になります。 これは、/airports/:code
の:code
に相当します。
ターミナルで、pages
の下にairport
という名前の新しいディレクトリを作成します。
mkdir pages/airport
airport
ディレクトリで、テキストエディタで_code.vue
という名前のファイルを作成し、次を追加します。
お気に入り-airports/pages / 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
プロパティがpages
ディレクトリのcode
パラメータと一致するデータをフェッチできるようになります。 Nuxtには、ここに関連する2つの追加のフックまたはライフサイクルメソッドがあります。fetch
とasyncData
です。 fetch
メソッドを使用して、ページがレンダリングされる前にネットワーク呼び出しを行うことができます。 asyncData
メソッドは、ページがレンダリングされる前にリアクティブデータをシェーピングするときに使用されます。
asyncData
内にあるリアクティブデータは、そのページのdata
にマージされます。 例として、次のコードを取り上げます。
export default { data() { return { lastName: 'Grohl' } }, asyncData() { const firstName = 'Dave' } }
これは、次のように書くのと同じです。
export default { data() { return { firstName: 'Dave', lastName: 'Grohl' } }, }
唯一の違いは、asyncData
がサーバーでレンダリングされるのに対し、data
はクライアントでレンダリングされることです。
asyncData
を試すには、airports.js
データセットからオブジェクトを返すfilterループを作成します。
お気に入り-airports/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 } } } </script>
このコードでは、airports.js
データをページにインポートし、abbreviation
とroute.params.code
が一致する場所を除くすべてのオブジェクトを除外します。 これはasyncData
フックで行われるため、airport
は、template
で使用できるデータプロパティになります。
データを使用するには、同じファイルのtemplate
セクションに次の強調表示された行を追加します。
お気に入り-airports/pages / 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 the <strong>{{ airport.abbreviation }}</strong> airport.</p> </div> </template> ...
このファイルを保存して、空港の略語を動的にレンダリングします。 ブラウザウィンドウを開いてhttp://localhost:3000/airport/cvg
にすると、テンプレートに空港コードが表示されます。 /airport/sea
などの別のコードで空港ルートにアクセスして、データが更新されていることを確認してください。
Nuxtで静的ルートと動的ルートを作成したので、これらのairports.js
オブジェクトのデータプロパティの表示に進むことができます。 次のセクションでは、Nuxtでlayouts
を作成し、それらをページに割り当てます。 それが完了したら、このステップで行ったことを活用して、より有用なデータをレイアウトに追加します。
ステップ3—Nuxtレイアウトの作成
Nuxtでは、ページのレイアウトを作成して、アプリケーションをよりモジュール化することができます。 これは、従来のVue.jsアプリでレイアウトコンポーネントを作成するプロセスと似ていますが、Nuxtでは、ページレベルのlayout
プロパティを介してレイアウトを割り当てます。 このステップでは、動的に生成された空港の詳細ページごとに再利用するレイアウトを作成します。
レイアウトを作成するには、最初にプロジェクトにlayouts
ディレクトリを作成します。
mkdir layouts
このディレクトリにAirportDetail.vue
という名前のファイルを作成して開きます。 このレイアウトでは、空港に関する情報を含むサイドバーが自動的に追加されます。 これを行うには、次のコードをファイルに追加します。
お気に入り-airports/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
パラメーターを介して空港オブジェクトを取得します。 テンプレートの<Nuxt />
要素は、ページのコンテンツが挿入される場所です。 これはVueスロットと同様に機能します。
次に、いくつかのTailwindクラスを活用します。 以下を追加して、レイアウトとスタイルを設定します。
お気に入り-airports/layouts / AirportDetail.vue
<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
でもあります。 aside
要素はサイドバーであり、main
要素はメインコンテンツです。
このグリッドを作成したら、いくつかのTailwindクラスを含むサイドバーを追加します。
お気に入り-airports/layouts / AirportDetail.vue
<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などのいくつかのスタイルが追加されます。 このサイドバーの内側に、いくつかの情報を入力します。
お気に入り-airports/layouts / AirportDetail.vue
<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> ...
このコードは、空港固有の詳細をページに追加し、テキストを中央に配置します。
先に進む前に、airport.name
を値として<h1>
を追加します。 これは、<Nuxt />
要素の上にあります。これは、次のレイアウトですべてのページに表示されるためです。
お気に入り-airports/layouts / AirportDetail.vue
<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
を開き、次の強調表示された行を追加します。
お気に入り-airports/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ストアにアクセスする方法が明確でない場合があります。 サーバー側のthis
を介してVueインスタンス全体にアクセスできないため、Nuxtはfetch
およびasyncData
フック。 このステップでは、context
を使用して、空港のページに動的なページの説明を追加します。
このチュートリアルの前のセクションでは、_code.vue
ファイルでcontext
オブジェクトをすでに使用しました。
お気に入り-airports/pages / airport / _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
などの標準名を付けることもできます。
お気に入り-airports/pages / airport / _code.vue
<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
メソッドもあります。 X185X]プロパティ。 このプロパティを使用すると、ページのレンダリング時にmeta
情報をDOM(ドキュメントオブジェクトモデル)の<head>
に挿入できます。 このプロパティの情報は、Webサーバーで読み取ることができます。
ページのdescription
を設定するには、テキストエディタで_code.vue
ファイルを開きます。
お気に入り-airports/pages / airport / _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
プロパティを追加し、description
プロパティを定義するオブジェクトの配列を使用してmeta
プロパティを追加しました。 これは、静的な.html
ページに次のように書き込むのと同じです。
<head> <title>Airport Information | Aiport App</title> <meta hid="description" name="description" content="Detailed information about the specific airport."> </head>
_code.vue
ファイルを保存して、ブラウザで開きます。 レンダリングされたDOMには、追加した情報が含まれます。
文字列補間を使用して現在の空港情報を<head>
要素に挿入することにより、title
およびdescription
を動的にすることもできます。
<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は、サーバー側でページを動的にレンダリングし、<head>
プロパティを使用してSEOを構成し、layout
プロパティを使用してコードをモジュール化するためのツールを提供します。 また、asyncData
とfetch
を使用してサーバーにレンダリングするデータ、またはdata
を使用してクライアントにレンダリングするデータを定義することもできます。
Nuxtの機能の詳細については、公式Nuxtドキュメントにアクセスしてください。 Vueのその他のチュートリアルについては、Vue.jsシリーズページを使用してWebサイトを開発する方法を確認してください。