Headless Oracle Content ManagementでNext.jsで最小のサイトを構築
イントロダクション
Next.jsは、サーバー側のレンダリングやReactベースのWebアプリケーション用の静的Webサイトの生成などの機能を可能にする、オープンソースのReactフロントエンド開発Webフレームワークです。
Next.jsアプリケーションでOracle Content Managementコンテンツを利用するために、GitHubのオープンソース・リポジトリとして使用可能なNext.js最小サンプルを使用できます。
このチュートリアルでは、Oracle Content ManagementをヘッドレスCMSとして活用し、JavaScriptのコンテンツ配信用のソフトウェア開発キット(SDK)を利用して、Next.jsでシンプルな最小のサイトを構築します。このNext.jsサンプルは、GitHubで入手できます。
チュートリアルは、次の3つのタスクで構成されています。
前提条件
このチュートリアルを続行する前に、次の情報を先にお読みください。
このチュートリアルに従うには、次のものが必要です。
- Oracle Content Managementのサブスクリプション
- コンテンツ管理者ロールを持つOracle Content Managementアカウント
- ノード・バージョン10以上のWindowsまたはMacコンピュータ
構築しているもの
Next.jsを最小限にすると、Oracle Content Managementリポジトリからイメージおよびその他のコンテンツを簡単に取得できます。
構築している内容をご覧いただくには、チュートリアルの終わりをご紹介します。この最終的な状況は、Oracle Content Managementからのコンテンツを消費するNext.jsの最小基本サイトです。
https://headless.mycontentdemo.com/samples/oce-nextjs-minimal-sample
このチュートリアルの最後には、ホーム・ページが表示されます。
このチュートリアルの最後にお問合せページが表示されます。
続行するには、Oracle Content Managementのアクティブなサブスクリプションを持ち、コンテンツ管理者ロールでログインする必要があります。
タスク1: Oracle Content Managementの準備
Oracle Content Managementインスタンスがまだない場合は、クイック・スタートを参照して、Oracle Cloudへの登録、Oracle Content Managementインスタンスのプロビジョニング、ヘッドレスCMSとしてのOracle Content Managementの構成方法を学んでください。
このチュートリアルでは、コンテンツ・モデルを作成する必要があります。ダウンロード可能なアセット・パックが使用可能で、空のリポジトリにはコンテンツ・タイプと関連するコンテンツが入力されます。
Oracle Content Managementを準備するには:
チャネルおよびアセット・リポジトリの作成
まず、コンテンツを公開できるように、Oracle Content Managementでチャネルおよびアセット・リポジトリを作成する必要があります。
Oracle Content Managementでチャネルおよびアセット・リポジトリを作成するには:
管理者としてOracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「チャネルの公開」を選択します。
右上隅にある「Create」をクリックして新しいチャネルを作成します。このチュートリアルの目的でチャネル'OCEMinimalChannel'に名前を付け、アクセスを公開したままにします。「保存」をクリックしてチャネルを作成します。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。
右上隅にある「Create」をクリックして、新しいアセット・リポジトリを作成します。このチュートリアルの目的で、アセット・リポジトリにOCEMinimalRepositoryという名前を付けます。
「チャネルの公開」フィールドで、OCEMinimalChannelチャネルを選択して、OCEMinimalRepositoryリポジトリのコンテンツをOCEMinimalChannelチャネルに公開できることをOracle Content Managementに示します。終了したら、「Save」をクリックします。
コンテンツ・モデルの作成
次のタスクは、コンテンツ・モデルを作成することです。次のいずれかのメソッドを使用できます。
Oracle Content Managementサンプル資産パックのインポート
このチュートリアルに必要なすべてのコンテンツ・タイプおよびアセットを含む、事前構成されたOracle Content Managementサンプル・アセット・パックをダウンロードできます。必要に応じて、サンプル資産パックをダウンロードするのではなく、独自のコンテンツ・モデルを作成することもできます。
このチュートリアルで使用しているコンテンツのコピーは、Oracle Content Management Sample Asset Packからアップロードできます。これにより、コンテンツ・タイプを試行し、コンテンツを変更できます。Oracle Content Managementサンプル資産パックをインポートする場合は、アセット・パック・アーカイブOCESamplesAssetPack.zipをダウンロードし、選択したディレクトリに抽出できます。
Oracle Content Managementのダウンロード・ページから、Oracle Content Managementサンプル資産パック(OCESamplesAssetPack.zip)をダウンロードします。ダウンロードしたzipファイルをコンピュータ上の場所に抽出します。抽出後、この場所にはOCEMinimal_data.zipというファイルが含まれます。
管理者としてOracle Content Management Webインタフェースにログインします。
左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「リポジトリ」を選択します。次に、OCEMinimalRepositoryを選択し、上部のアクション・バーの「コンテンツのインポート」ボタンをクリックします。
ローカル・コンピュータから「ドキュメント」フォルダにOCEMinimal_data.zipをアップロードします。
アップロード後、「OCEMinimal_data.zip」を選択し、「OK」をクリックしてコンテンツをアセット・リポジトリにインポートします。
コンテンツが正常にインポートされたら、「アセット」ページに移動し、OCEMinimalRepositoryリポジトリを開きます。すべての関連イメージおよびコンテンツ・アイテムがアセット・リポジトリに追加されていることがわかります。
左上の「すべて選択」、「公開」の順にクリックして、インポートされたすべてのアセットを、前に作成した公開チャネル(OCEGettingStartedChannel)に追加します。
公開する前に、すべてのアセットを検証する必要があります。まず、選択したチャネルとしてOCEMinimalChannelを追加し、「検証」ボタンをクリックします。
アセットが検証されたら、右上隅にある「公開」ボタンをクリックして、選択したチャネルにすべてのアセットを公開できます。
これが完了すると、「アセット」ページで、すべてのアセットが公開されていることを確認できます。(アセット名の上のアイコンで確認できます。)
Oracle Content Management Sample Asset Packのインポート後、Next.jsでの最小サイトの作成を開始できます。
独自のコンテンツ・モデルの作成
Oracle Content Management Sample Asset Packのインポートではなく、独自のコンテンツ・モデルを作成することもできます。
このチュートリアルでは、このサンプルのメイン・コンテンツ・タイプとして「MinimalMain」というコンテンツ・タイプを使用しています。このコンテンツ タイプは、ヘッダーおよびフッターのロゴと、ナビゲーションに含めるページのリストで構成されます。
コンテンツ・モデルのコンテンツ・タイプを作成するには:
- 管理者としてOracle Content Management Webインタフェースにログインします。
- 左側のナビゲーション・メニューで「コンテンツ」を選択し、ページ・ヘッダーの選択リストから「アセット・タイプ」を選択します。
- 右上隅の「作成」をクリックします。
- コンテンツ・タイプ(デジタル・アセット・タイプではない)の作成を選択します。すべての必須コンテンツ・タイプについて、これを繰り返します。
3つのコンテンツ・タイプを作成し、それぞれに独自のフィールド・セットを作成します。
- MinimalMain
- MinimalPage
- MinimalSection
最初のコンテンツ・タイプMinimalMainには、次のフィールドが必要です。
表示名 | フィールド・タイプ | 必須 | マシン名 |
---|---|---|---|
headerLogo | シングルバリュー・メディア・フィールド | headerLogo | |
footerLogo | シングルバリュー・メディア・フィールド | footerLogo | |
ページ | 複数値参照フィールド | ページ |
MinimalMainコンテンツ・タイプ定義は次のようになります。
2つ目のコンテンツ・タイプMinimalPageには、次のフィールドが必要です。
表示名 | フィールド・タイプ | 必須 | マシン名 |
---|---|---|---|
セクション | 複数値参照フィールド | セクション |
MinimalPageコンテンツ・タイプは次のようになります。
3番目および最後のコンテンツ・タイプMinimalSectionには、次のフィールドが必要です。
表示名 | フィールド・タイプ | 必須 | マシン名 |
---|---|---|---|
type | 単一値テキスト・フィールド | X | type |
ヘディング | 単一値テキスト・フィールド | ヘディング | |
本体 | 単一値の大型テキスト・フィールド | 本体 | |
画像 | シングルバリュー・イメージ・フィールド | イメージ | |
アクション | 単一値の埋込みコンテンツ・フィールド | アクション |
MinimalSectionコンテンツ・タイプは次のようになります。
コンテンツ・タイプを作成したら、次のコンテンツ・タイプを前に作成したリポジトリOCEMinimalRepositoryに追加できます。
- 管理者としてOracle Content Management Webインタフェースにログインします。
- OCEMinimalRepositoryに移動します。
- リポジトリを編集し、「アセット・タイプ」で、新しく作成された3つのコンテンツ・タイプをすべて指定します。「保存」ボタンをクリックして変更を保存します。
コンテンツ・タイプをリポジトリに追加した後、「アセット」ページでOCEMinimalRepositoryリポジトリを開き、すべてのコンテンツ・タイプのコンテンツ項目の作成を開始できます。
タスク2: Next.jsでの最小サイトの作成
サーバー側のレンダリングされたNext.jsアプリケーションでOracle Content Managementコンテンツを利用するには、GitHubのオープンソース・リポジトリとして使用できるNext.js最小サイト・サンプルを使用します。
ノート: Next.jsサンプルの使用はオプションであり、このチュートリアルで使用してすぐに開始できるようにしてください。独自のNext.jsアプリケーションを構築することもできます。
Next.jsで最小サイトを作成するには:
- サンプル・リポジトリのクローニングと依存関係のインストール
- Next.jsアプリケーションの構成
- Oracle Content Management Content SDKの使用
- コンテンツSDKを使用したコンテンツのフェッチ
サンプル・リポジトリのクローニングとインストールの依存性
Next.js最小サイト・サンプルは、GitHubのオープンソース・リポジトリとして使用できます。
まず、サンプルをGitHubからローカル・コンピュータにクローニングし、ディレクトリをリポジトリ・ルートに変更する必要があります。
git clone https://github.com/oracle/oce-nextjs-minimal-sample.git
cd oce-nextjs-minimal-sample
コード・ベースがあるので、アプリケーションの依存関係をダウンロードする必要があります。rootディレクトリから次のコマンドを実行します。
npm install
Next.jsアプリケーションの構成
このNext.jsの最小サイト・サンプルでは、Oracle Content Management Content SDK (およびその他のリクエスト)が適切なチャネル・トークンを使用して正しいインスタンスURLおよびAPIバージョンをターゲットにできるように、いくつかの情報を構成する必要があります。これらの値は、Script/server-config-utils.jsで新規配信クライアントをインスタンス化するために使用されます。
このアプリケーションは、Next.jsによって読み取られ、process.envを使用してアプリケーション内のコードで使用できるようにする.env.localファイルを使用します。
.env.localファイルをテキスト・エディタで開きます。次のようなものが表示されます。
# The connection details for the Oracle Content Management server to be used for this application
SERVER_URL=https://samples.mycontentdemo.com
API_VERSION=v1.1
CHANNEL_TOKEN=ba0efff9c021422cb134c2fd5daf6015
各キーと値のペアを変更して、インスタンスURL、ターゲットとするAPIバージョン、および公開チャネルに関連付けられたチャネル・トークンを反映します。このチュートリアルのチャネルはOCEMinimalChannelです。
Oracle Content Management Content SDKの使用
Oracle Content Managementには、アプリケーションのコンテンツの検出および使用に役立つSDKが用意されています。SDKはNPMモジュールとして公開され、プロジェクトはGitHubでホストされます。
SDKの詳細は、ここを参照してください。
SDKは、package.jsonファイルのこのプロジェクトの実行時依存性として登録されました。
コンテンツSDKを使用したコンテンツのフェッチ
Content SDKを活用してコンテンツをフェッチし、Next.jsアプリケーションでレンダリングできるようになりました。
Content SDKでは、DeliveryClientオブジェクトを使用してエンドポイントを指定します。そのクライアント・オブジェクトを使用してすべてのリクエストを作成できます。
scriptフォルダには、Content SDKを使用してOracle Content Managementからデータを取得するためのコードが含まれます。
script/server-config-utils.jsファイルは、Content SDKをインポートし、.env.localで指定されている構成を使用して配信クライアントを作成します。
次のコマンドは、SDKをインポートします。
import { createDeliveryClient, createPreviewClient } from '@oracle/content-management-sdk';
次のコマンドは、配信クライアントを作成します。
return createDeliveryClient(serverconfig);
script/services.jsファイルには、このNext.js最小アプリケーションのデータを取得するための関数が含まれています。
fetchOceMinimalMain()メソッドは、最小限の余裕のあるコンテンツ・タイプMinimalMainを取得します。
export async function fetchOceMinimalMain() {
const data = await getItem('minimalmain', 'fields.headerlogo,fields.footerlogo,fields.pages');
if (!data.hasError) {
const { fields } = data;
const { headerlogo, footerlogo } = fields;
// Extract the sourceset for the headerImage and footerImage and put it back in the data
.headerRenditionURLs = getSourceSet(headerlogo);
data.footerRenditionURLs = getSourceSet(footerlogo);
data
}return data;
}
イメージをレンダリングするために、service.jsには、アセットのレンディションから構築されたアセットのソース・セットを取得するヘルパー・メソッドが用意されています。
function getSourceSet(asset) {
const urls = {};
.srcset = '';
urls.jpgSrcset = '';
urlsif (asset.fields && asset.fields.renditions) {
.fields.renditions.forEach((rendition) => {
assetaddRendition(urls, rendition, 'jpg');
addRendition(urls, rendition, 'webp');
;
})
}// add the native rendition to the srcset as well
.srcset += `${asset.fields.native.links[0].href} ${asset.fields.metadata.width}w`;
urls.native = asset.fields.native.links[0].href;
urls.width = asset.fields.metadata.width;
urls.height = asset.fields.metadata.height;
urlsreturn urls;
}
fetchPage()メソッドは、ページのスラグ値を使用してコンテンツ・タイプMinimalPageを取得します。
export async function fetchPage(pageslug) {
// Get the page details
const page = await getItem(pageslug, 'fields.sections');
return page;
}
getRenditionURLs()メソッドは、そのイメージのIDを使用してセクションに定義できるイメージのレンディションURLを取得します。
export function getRenditionURLs(identifier) {
const client = getClient();
return client.getItem({
id: identifier,
expand: 'fields.renditions',
.then((asset) => getSourceSet(asset))
}).catch((error) => logError('Fetching Rendition URLs failed', error));
}
データ問合せがあるため、Next.jsコンポーネントでレスポンスをレンダリングできます。
Next.jsコンポーネント
Next.jsはReactとReactに基づいており、JavaScriptのHTMLに似た構文拡張であるJSXと呼ばれるテクノロジーを使用してコンテンツをレンダリングしています。Oracle Content Managementからデータをレンダリングするために純粋なJavaScriptを記述できますが、JSXを使用することを強くお薦めします。
最小サイト・アプリケーションは、各ページを多数の小さなコンポーネントに分割します。
次の数セクションでは、各コンポーネントでNext.jsによってアプリケーションをレンダリングする方法の概要を説明します。
ページ・フォルダ
当社では、/pageという1つのルートを提供しています。リクエストは、page/[[..slug]].jsxファイルに定義されているメイン コンポーネントに転送されます。next.config.jsでリダイレクトを指定することで、ルート・パス・リクエストが/ページにリダイレクトされます。
async redirects() {
return [
{source: '/',
destination: '/page/',
permanent: true,
,
}
] }
すべてのページには、会社のロゴとリンクを含むヘッダーと、ロゴおよびソーシャル・メディア・アイコンを含むフッターがあります。ページは静的URLを介してアクセスされ、関連するデータを子コンポーネントに渡す前に必要なすべてのデータを取得します。
Next.jsでは、ページ・ディレクトリ内のすべてのページがアプリケーションのルートとして処理されます。
メイン・コンポーネント
すべてのページは、ページ/[[..slug]].jsxにあるメイン コンポーネントによってレンダリングされます。Next.jsのすべてのルートの捕捉は、二重カッコ([[...slug]])にパラメータを含めることでオプションです。「ページ」リストの最初のページにデフォルト設定されたルート・ページにはパラメータが渡されないため、スラグ・パラメータはオプションとして定義します。
コンポーネントは、service.jsファイルからデータを取得するためにAPIをインポートします。
import { fetchOceMinimalMain, fetchPage, getRenditionURLs } from '../scripts/services';
ページのURLは、ページ・スラグがパスとして含まれている動的URLです。たとえば、URLパスは次のようになります。
- /page/home
- /page/contact-us
- /page
Next.jsが動的URLを持つページに静的サイト生成を使用する場合、getStaticPaths()を呼び出してそのページのすべてのパスを取得します。
export async function getStaticPaths() {
const appData = await fetchOceMinimalMain();
const { fields } = appData;
// Generate the paths we want to pre-render based on posts
const paths = fields.pages.map((page) => ({
params: { slug: [page.slug] },
;
}))// Also add the path for the root /
.push({
pathsparams: { slug: [] },
;
})return {
,
pathsfallback: false,
;
} }
getStaticProps()ファンクションは、ページの単一インスタンスのデータを取得するために使用されます。ページ・スラグは、メソッドに渡されるパラメータから取得されます。ページ・スラグは、このページに必要なすべてのデータを取得するために使用されます。
export async function getStaticProps(context) {
// fetch the minimal main data
const appData = await fetchOceMinimalMain();
// find the slug param from the context. If its null, default to the first page slug
const { params } = context;
let { slug } = params;
if (slug == null) {
= appData.fields.pages[0].slug;
slug
}// fetch the page corresponding to the slug
const pageData = await fetchPage(slug);
const { headerRenditionURLs, footerRenditionURLs, fields } = appData;
const { sections } = pageData.fields;
// for each section in the page, if a image is present, get the corresponding rendition urls
// and insert it back into the section
const promises = [];
.forEach((section) => {
sections// add a promise to the total list of promises to get any section rendition urls
if (section.fields.image) {
.push(
promisesgetRenditionURLs(section.fields.image.id)
.then((renditionURLs) => {
// eslint-disable-next-line no-param-reassign
.renditionURLs = renditionURLs;
section,
});
)
};
})
// execute all the promises and return all the data
await Promise.all(promises);
return {
props: {
,
headerRenditionURLs,
footerRenditionURLspages: fields.pages,
,
pageData,
};
} }
ページ・コンポーネント
ページ・コンポーネントは、ページに定義されているすべてのセクションのレンダリングを担当します。コンポーネント/Page.jsxにあるPageコンポーネントを開きます。メイン・コンポーネントから渡されたデータを使用するだけです。サーバーから追加データは取得されません。セクション データをレンダリングするには、セクション コンポーネントを使用します。
.propTypes = {
PagepageData: PropTypes.shape().isRequired,
; }
ヘッダーおよびフッターのコンポーネント
コンポーネント/Header.jsxおよびフッター・コンポーネントにあるヘッダー・コンポーネントは、コンポーネント/Footer.jsxにあるため、メイン・コンポーネントから渡されるデータのみを使用します。サーバーから追加データは取得されません。
セクション・コンポーネント
コンポーネント/Section.jsxにあるセクション・コンポーネントは、ページ・コンポーネントによって使用され、MinimalSectionタイプのコンテンツ・アイテムのレンダリングに使用されます。
このコンポーネントには、ページ・コンポーネントから渡されるデータがあります。
エラーコンポーネント
コンポーネント/Error.jsxにあるErrorコンポーネントは、ページおよびメイン・コンポーネントで使用されます。サーバーへのコール中にエラーが発生した場合は、エラーがレンダリングされます。
タスク3:デプロイのためのアプリケーションの準備
Next.jsのブログ・サイトが構築されたので、問題のデバッグやアプリケーションのプレビューを行う前に、ローカル開発サーバーでこのサイトを確認する必要があります。
デプロイメント用のアプリケーションを2つのステップで準備します。
ローカル開発サーバーのスピン・アップ
次のコマンドを実行して開発サーバーをローカルで起動できます。
npm run dev
次に、ブラウザをhttp://localhost:3000に開き、実際のサイトを表示します。
ノート:ページは事前にレンダリングされません。ページを事前にレンダリングするには、次のセクションを参照してください。
スクリプトを使用した開発と本番でのアプリケーションの構築および実行
本番の場合、ビルド・スクリプトはサイトの静的に生成するために使用されます。
npm run build
startスクリプトは、静的に生成されたページを提供するNode.jsサーバーを起動するために使用されます。
npm run start
Headless Oracle Content ManagementでNext.jsで最小のサイトを構築
F49332-01
2021年10月
Copyright © 2021, Oracle and/or its affiliates.
原本著者: Oracle Corporation