積読ハウマッチをNuxt.jsのSPAで作ってみたけど、
静的ページじゃないので、NuxtのSitemap Moduleだと微妙...
なので、CloudFunction for Firebaseを使って、
サイトマップを自動生成するようにしてみたときの備忘録。
sitemap.xmlのサンプル
sitemapの形式はこんな感じ。必須なのは<loc>
だけなので、
とりあえず、そこだけあればいい感じ。
<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <url> <!-- 必須: URL --> <loc>http://www.example.com/</loc> <!-- 任意: 最終更新日 --> <lastmod>2005-01-01</lastmod> <!-- 任意: 更新頻度。always/daily/yearly/neverなども --> <changefreq>monthly</changefreq> <!-- 任意: 優先度: 0.0〜1.0で指定。デフォルトで0.5 --> <priority>0.8</priority> </url> <url> <!-- 以後、繰り返し --> </url> </urlset>
Hostingの設定
ホスティング側の設定をして、Functionを呼び出すように変更。
{ // ...略 "hosting": { // ...略 "rewrites": [ { "source": "/sitemap", "function": "sitemap" }, // ...略 ], }, }
Functionのコード
Function側のコードはこんな感じ。とりあえず<loc>
だけ対応
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); const db = admin.firestore(); // ******************************************************** // * サイトマップの生成 // ******************************************************** exports.sitemap = functions.https.onRequest(async (req, res) => { try { const lines = []; // head lines.push(`<?xml version="1.0" encoding="UTF-8"?>`); lines.push(`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`); // root lines.push(`<url><loc>https://example.com/</loc></url>`); // userの個別ページ const userDocs = await db.collection("users").get(); userDocs.docs.map(s => { lines.push(`<url><loc>https://example.com/user/${s.data().uid}</loc></url>`); }); // end lines.push(`</urlset>`); // キャッシュを有効に res.set("Cache-Control", "public, max-age=7200, s-maxage=600"); // コンテントタイプをxmlに res.set("Content-Type", "text/xml"); // リストを改行でJOINして、レスポンスを返す res.end(lines.join("\n")); } catch (error) { // なにかエラーがあったら、静的ファイルの方へリダイレクト console.error(`Error occuered in sitemap: ${error}`, error); res.redirect("/sitemap.xml"); } });
これで、Firestoreにあるデータも踏まえたsitemap.xmlを作れるように(´ω`)
結果はこんな感じ
固定なURLはトップページしかなかったので、
@nuxtjs/sitemapを使うと1だったけど...
DBデータから自動生成もしたので、5052ページに♪
以上!!