免責
- Sparkプランの上でやったことなので、上位プランならもうちょっとスマートな方法があったかもしれません
-
firebase.json
の設定次第ではもっとスマートな方法があったかもしれません - やったことのログがメインとなります
何をやったか
Firebase
で運用しているWebサイトのrobots.txt
を、Firebase Hosting
ではなくCloud Functions
を使って、ドメインごとに別の内容を配信するようにしました。
動機
自サイトをFirebase
で運用しています。 静的コンテンツの配信ならFirebase Hosting
が一番楽ですが、ここを利用すると最初に次のドメインが割り当てられます。
{PROJECT_ID}.web.app
{PROJECT_ID}.firebaseapp.com
カスタムドメインを使いたい場合も割と簡単で、Firebase
のコンソール上で指示に従ってドメインを登録すれば割とあっさり運用可能になります。便利ですね。
ただ、ちょっと困ったことがあって、デフォルトのドメインを無効化出来ないっぽいです。1
すると、こんな事件が起きます。
デフォルトドメインもクロールされてる...!?
動作確認込みでデフォルトドメインも使ってたとは思うのですが、これは何かカッコ悪い気がします。
というわけで、
- カスタムドメインでは、サイトマップなどの情報を提供できる
robots.txt
を配信 - デフォルトドメインでは、せめてbot等によるクロールをしないでもらうための
robots.txt
を配信
という対応を取ることにしました。
Firebase Hosting
やfirebase.json
ではダメなのか?
とりあえず、現時点では以下のような理由で「なんかダメっぽい」と仮置きしています。
ホスティング環境が分断できてない
カスタムドメインもデフォルトドメインも同じホスティングコンテンツを参照するようになってます。
そのため、配置できるrobots.txt
は1個だけという判断をしています。
マルチサイト?結局ドメインが増えちゃうので問題解決にならないんじゃないかなと思ってます 2
firebase.json
は?
firebase.json
はリクエストに対する振る舞いが結構柔軟なのですが、ドメインによる振る舞い分岐を見つけられていません。
今のところは、多分出来ないんじゃないかなという判断をしてます。
Cloud Functionsで賄う
というわけで、苦肉の策として「/robots.txt
だけはCloud Functions
で配信する」という方針を取ることにしました。
実コード
import * as functions from 'firebase-functions';
const robotsAllow = `
sitemap: https://example.com/sitemap.xml
`
const robotsDisallow = `
User-agent : *
Disallow : /
`
export const ROBOTS_TXT = functions.https.onRequest((req, res) => {
const host = req.header('X-Forwarded-Host');
const robotsTxt = host === 'example.com' ? robotsAllow : robotsDisallow;
res.type('txt')
.set('Cache-Control', 'public, max-age=7200, s-maxage=3600')
.send(robotsTxt.trim())
.end();
});
やったことの分割整理
複数のrobots.txt
を用意する
ファイルに持たさたりするなど、いくつかパターンが有りましたが、ワンソースで雑に解決したかったので、
「robotsAllow
にカスタムドメイン向けのテキスト」「robotsDisallow
にデフォルトドメイン向けのテキスト」と、
変数で管理するようにしました。
アクセスしてきたドメイン名でrobotsTxt
を決定
Cloud Function
のHTTPトリガー処理はリクエストヘッダーとしてX-Forwarded-Host
を受け取ります。
この中身がまさに「アクセスしてきたドメインが何か」を持っているため、この中身をベースに「どちらのrobots.txtを配信するか」を決定します。
レスポンスする
res
オブジェクトを使って、粛々と中身をレスポンス。追加で次のことをしています。
- MIMEタイプを変えるために、
type()
を呼び出し 3 - 頻繁に関数を呼び出しされるのもあれなので、とりあえず
Cache-Control
で多少はキャッシュしてもらう -
robotsTxt
の中身は先頭と末尾に改行がいるので、trim()
で整形
振り返り
リライト設定だしHostingがCDN相当の振る舞いをしてくれたりするので、ついCloud Functions
で利用しがちです。
ただ、コストを考えたほうがいいとは思いつつ、「最小限の労力で必要十分な結果を得る」にはこれぐらいの感覚で利用してよいのかなとも思いました。