NuxtJSでhead内のbaseタグをhooksを使って無理やり消してAMPエラー解消した
ちょっと無理やりなややこしいことをしたのでその経緯を含めてメモ。設定でできるようになるといいな。
NuxtJSでAMP対応をしてますが、router.baseを設定しサブディレクトリに公開しているため、headにbaseタグが入ってしまい、これがAMPテストツールのエラーの原因になっていました。
テストツールはこれ→https://search.google.com/test/amp?hl=ja
一通りググったけどそれらしい方法は見つからず。
サブディレクトリかつ、AMP対応というレアケースのためでしょうか。
ドキュメントには
base がセットされているときは Nuxt.js はドキュメントのヘッダーに
を追加します。
と書いてあるだけで消し方などは書いてありません。
pageファイル内のhead()で試しましたがダメ。
ということでソースコードにあたりました。デフォルトブランチへのリンクなので変わってしまうかも。
今日(2020/7/2)時点のdevブランチだと、SSRの場合ここでbaseタグを挿入してます。
github.com
文字列連結してるのでhead()でいじれないのは当たり前でした。
// Add <base href=""> meta if router base specified if (this.options._routerBaseSpecified) { HEAD += `<base href="${this.options.router.base}">` }
this.options._routerBaseSpecifiedを変える手もあるかと思いましたが今後、他でも使われるかもしれないし、_がついてるので触っちゃだめなはず。nuxt.config.jsからも渡せません。
何か方法はないものかと、ソースコードをたどるとhookというものを見つけました。
https://github.com/nuxt/nuxt.js/blob/dev/packages/vue-renderer/src/renderers/ssr.js#L268
await this.serverContext.nuxt.callHook('vue-renderer:ssr:templateParams', templateParams, renderContext)
hookの使い方の例はここにありました。
API: hooks プロパティ - NuxtJS
import fs from 'fs' import path from 'path' export default { hooks: { build: { done (builder) { const extraFilePath = path.join(builder.nuxt.options.buildDir, 'extra-file') fs.writeFileSync(extraFilePath, 'Something extra') } } } }
ということでやってみた。vue-renderer:ssr:templateParamsをコロンで切ってオブジェクト化して、最後を関数にすればいいらしい。
nuxt.config.js
export default { hooks: { 'vue-renderer': { ssr: { templateParams(templateParams, renderContext) { // AMPページでbaseタグを無理やり消してる if (renderContext.url && renderContext.url.match(/\/amp\/?$/)) { templateParams.HEAD = templateParams.HEAD.replace( `<base href="${BASE_PATH}/">`, '' ) console.log('base tag removed', renderContext.url) } }, }, }, },
今回baseタグを消すのは、AMPページだけでいいので判定にはrenderContext.urlの最後に/amp/が付いているかどうかを使いました。
というかこれぐらいしか見つからなかった。
これで無事?AMPページだけ消えました。
設定でやりたいから要望、プルリクを思ったけどレアケースかもしれないので悩んでる。