ほそぼそと作ってるマグロのタッチゲーム、
いちようLPを作ってみた(*´ω`*)
普段、Nuxt.jsでWebアプリとかを作るけど、
最近のモジュールをいろいろ試してみたときの備忘録(*´ω`*)
使ったモジュール/構成
構成はこんな感じ。
内包しているのを合わせるとこんな感じ。
- @nuxt/content
- @nuxtjs/i18n
- @nuxt/ui
- @nuxt/fonts
- Nuxt SEO(@nuxtjs/seo)
- @nuxt/gtm
- stefanobartoletti/nuxt-social-share: Simple Social Sharing for Nuxt 3
はじめは@nuxt/imageも使ってけど、
使うほどでもない&バンドルサイズを下げたいので、使わない形に。
Nuxt Content
まずはテンプレートで作成
$ pnpm dlx nuxi init my-docs -t content
Document Drivenモードもあるけど、
多くの問題があり、次のバージョンでなくなるらしい。。
Nuxt UI
UIコンポーネントなどは、Nuxt UIを利用
TailwindやIconifyなどで構成されているので便利
$ pnpm add -D @nuxt/ui # material iconも使いたいので、追加 $ pnpm add -D @iconify-json/mdi
nuxt.config.tsの設定
nuxt.config.ts
に設定を追加しておく
// nuxt.config.ts export default defineNuxtConfig({ static: true, modules: [ '@nuxt/content', '@nuxt/ui', ], // ******************************************************** // * @nuxt/content: https://content.nuxt.com/ // ******************************************************** content: { }, // ******************************************************** // * @nuxt/ui: https://ui.nuxt.com/ // ******************************************************** ui: { // .mdからコンポーネントが使えるようにglobal importにする global: true, // 利用するiconの種類を指定 icons: ['mdi', "heroicons"], }, // ******************************************************** // * @nuxt/color-mode: https://color-mode.nuxtjs.org/ // ******************************************************** colorMode: { preference: "light", }, });
tailwind.configの設定
content/**/*.md
でもtailwindcssの対象になるように設定
// tailwind.config.ts import type { Config } from 'tailwindcss'; export default <Partial<Config>>{ content: [ 'content/**/*.md' ] };
VSCodeの設定
Tailwindでの補完に関するVSCodeの設定を追加
// .vscode/settings.json { "files.associations": { "*.css": "tailwindcss" }, "editor.quickSuggestions": { "strings": true }, "tailwindCSS.experimental.configFile": "tailwind.config.ts", // or "tailwindCSS.experimental.configFile": { "my-docs/tailwind.config.ts": "my-docs/**" } }
Nuxt Fonts/Google Fonts
こんな感じで、フォント名(Roboto
)を書くだけで、
assetsにダウンロードしてくれるモジュール
<template> <div> Hello Nuxt Fonts! </div> </template> <style scoped> div { font-family: Roboto, sans-serif; } </style>
$ pnpm add -D @nuxt/fonts
// nuxt.config.ts export default defineNuxtConfig({ static: true, modules: [ '@nuxt/content', '@nuxt/ui', "@nuxt/fonts", ], // 略 });
TailwindCSSを使っていても、認識してくれるらしい
Nuxt Fontsはassetsにダウンロードして、
自分のサイトから配信する形
自身では配信せず、もとのGoogle FontsのURLから取得したい場合は、
@nuxtjs/google-fonts
のほうがよいかも
@nuxtjs/google-fonts
の場合は、こんな感じ
// nuxt.config.ts export default defineNuxtConfig({ static: true, modules: [ // 略 '@nuxtjs/google-fonts', ], // 略 // ******************************************************** // * @nuxtjs/google-fonts: https://google-fonts.nuxtjs.org // ******************************************************** googleFonts: { families: { "Kaisei Tokumin": true, } }, });
Nuxt i18n
英語版も用意したいので、nuxt-i18nも導入
$ pnpm add -D @nuxtjs/i18n
設定はこんな感じ
// nuxt.config.ts export default defineNuxtConfig({ static: true, modules: [ // 略 '@nuxtjs/i18n', ], // 略 // ******************************************************** // * @nuxtjs/i18n: https://i18n.nuxtjs.org // ******************************************************** i18n: { // デフォルトの言語 defaultLocale: "ja", // パスに言語を含めるかどうか。デフォルト以外は含める設定 strategy: "prefix_except_default", baseUrl: "<BASE_URL>", // ブラウザの言語を使って切り替えるかどうか detectBrowserLanguage: false, // 利用できる言語の一覧 locales: [ { code: "ja", iso: "ja", name: "日本語" }, { code: "en", iso: "en", name: "English" }, ], }, });
あとは、多言語ファイルを用意。
export default defineI18nConfig(() => ({ legacy: false, messages: { en: { title: "MAGURO Finding", desc: "A simple casual game to find tuna among mackerel", }, ja: { title: "マグロ探し", desc: "鯖(サバ)の中から鮪(マグロ)を探す無料のシンプルカジュアルゲーム", }, } }));
手前味噌だけど、SSSAPIを使うと、
スプレットシートからいい感じのJSONを取得できるので、そのまま使ってる
https://sssapi.app/help/sample4
// curlとかで、SSSAPIからi18n.jsonを取得&保存 import i18Json from "./i18.json"; export default defineI18nConfig(() => ({ legacy: false, messages: i18Json }));
Nuxt SEO(@nuxtjs/seo)
SEO系はsitemapとrobots.txtだけ対応
基本的にURLだけ指定すれば、Nuxt SEOが
i18nも考慮したパスでsitemapとかを作ってくれる
// nuxt.config.ts export default defineNuxtConfig({ static: true, modules: [ // 略 'nuxt-simple-robots', '@nuxtjs/sitemap', ], // 略 // ******************************************************** // * Nuxt SEO: https://nuxtseo.com/ // ******************************************************** // サイト全体の設定 site: { url: "<BASE_URL>", }, // robots.txtの設定 robots: { disallow: [], }, // sitemapの設定 sitemap: { }, });
ページごとのtitleとかは、Nuxt標準のuseHead
や<Head>
を使って設定する感じ
動的ページでOGPを生成したい場合は、
Nuxt OG Imageを使えばOK。
Vueコンポーネントなどを画像化してくれる。
@nuxt/gtm
Google Tag Managerを使いたいので、
Nuxt-GTMを導入
// nuxt.config.ts export default defineNuxtConfig({ static: true, modules: [ // 略 '@zadigetvoltaire/nuxt-gtm', ], // 略 // ******************************************************** // * @zadigetvoltaire/nuxt-gtm: https://github.com/zadigetvoltaire/nuxt-gtm // ******************************************************** gtm: { id: "GTM-XXXXXXXX", }, });
これだけでOK。vue-gtm
のラッパーモジュールなので、
細かいイベント送信とかは、こちらも合わせて読みつつ
Google Analytics 4の場合は、Nuxt Gtagを使えばOK
export default defineNuxtConfig({ modules: ['nuxt-gtag'], gtag: { id: 'G-XXXXXXXXXX' } })
シェア機能
シェア機能もつけたいなと思ったら、便利なライブラリがあったので導入
これだけで、いまのURLをシェアできるように(*´ω`*)
SSGの場合は<ClientOnly>
で囲むか、url
パラメタを指定する必要がある。
<template> <ClientOnly> <SocialShare network="twitter" :styled="true" :label="true" class="text-white" /> </ClientOnly> <template>
小ネタ
i18nでのmetaタグはapp.vueを使う
i18n側でhead.meta
などを用意してくれてる。
各言語用のOGPやtitleなどを設定したい場合は、
app.vue
に書いておくのがよい感じ。
<template> <Html :lang="head.htmlAttrs.lang" :dir="head.htmlAttrs.dir"> <Head> <template v-for="meta in head.meta" :key="meta.id"> <Meta :hid="meta.property" :name="meta.property" :property="meta.property" :content="meta.content" /> </template> <template v-for="link in head.link" :key="link.id"> <Link :id="link.id" :rel="link.rel" :href="link.href" :hreflang="link.hreflang" /> </template> </Head> <Body> <NuxtLayout> <NuxtPage /> </NuxtLayout> </Body> </Html> </template> <script setup lang="ts"> const { t, locale } = useI18n(); const baseUrl = useRuntimeConfig().public.baseUrl; const head = useLocaleHead({ addDirAttribute: true, identifierAttribute: 'id', addSeoAttributes: true, }); const ogImageFileName = computed(() => { if (locale.value == "ja") return `${baseUrl}/ogp.png`; else return `${baseUrl}/ogp_en.png`; }); useSeoMeta({ ogType: "website", title: t("title"), ogTitle: t("title"), description: t("desc"), ogDescription: t("desc"), ogImage: ogImageFileName, }); </script>
i18nとcontentの使い分け
単語や文ならnuxt-i18nを使い、
長い文書とかならnuxt-contentを使うのがいいらしい
i18n 対象となるコンテンツで使い分ける感じですね。あらかじめページ単位の場合は、nuxt-content、単語、小さい文レベルのときは、nuxt-i18n を使うという感じですね。
— 🐤kazupon🐤 (@kazu_pon) April 3, 2024
vuefes 2023 のサイト、どちらとも使っているので参考になればと。https://t.co/2j90c7jN4a
そのまま、ディレクトリをわけて記事全体を用意する形でもいいし、
content/ en/ index.md index.md
こんなコンポーネントを作っておくのでもOK
<!-- components/PartsArticle.vue --> <template> <div class="text-white font-bold prose prose-sm sm:prose-lg"> <ContentDoc :path="mdPath" :head="false" /> </div> </template> <script setup lang="ts"> const { locale } = useI18n(); const mdPath = computed(() => { if (locale.value == "ja") return `/_parts_article`; else return `/en/_parts_article`; }); </script>
SSGではdetectBrowserLanguageはOFFがいいかも?
ブラウザの言語を検出して、リダイレクトしてくれる機能があるけど、
SSGの場合は、うまく言語が切り替わらないなどあり、OFFにするようにした。
設定がよくない気がするので、時間に余裕があるときに再チャレンジしたい。。
デフォルト言語だけのページは、pages/
に用意する
表示している言語で遷移先のパスを指定するとき、
nuxt-i18nではlocalePath
を使う。
<template> <nuxt-link :to="localePath('/')"> {{ t("app.title") }} </nuxt-link> </template> <script lang="ts" setup> const localePath = useLocalePath(); const { t } = useI18n(); </script>
デフォルトの言語しか用意していないページの場合、
同じページを複製するのも大変なので、
pages/
にパスにあったvueを配置して切り替えないようにした。
うまくできる方法があるといいけど、また時間に余裕があるときに。。
以上!! 公式モジュールだけで、簡単にLP/ドキュメントサイトが作れるのはいいね(´ω`)
markdownを追加だけで、ヘルプとかお知らせとかも追加できる!!
作ってるゲームも事前予約受付中なので、
こちらもよろしくおねがいします〜(*´ω`*)