[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fpY71m_uWncVJIPChV30D6hlSgUkbOaDz0j9y6ULce-0":3,"profile":19050},[4,2457,5151,9726,10586,12555,13867,14654,16408,18453],{"id":5,"title":6,"body":7,"date":2442,"description":2443,"extension":381,"icon":2444,"meta":2445,"navigation":419,"ogImage":2446,"path":2447,"published":419,"publishedAt":2448,"seo":2449,"stem":2450,"tags":2451,"updatedAt":2455,"__hash__":2456},"tech/tech/nuxt-content-scheduled-posts.md","Nuxt Content で作ったブログの予約投稿を実装する",{"type":8,"value":9,"toc":2423},"minimark",[10,15,19,22,25,28,31,38,41,44,47,50,53,57,60,63,72,75,79,82,93,96,99,102,110,114,121,361,370,373,376,426,469,473,476,480,483,809,816,820,823,829,1568,1572,1575,1580,1667,1671,1860,1863,1867,2128,2132,2135,2229,2409,2413,2416,2419],[11,12,14],"h2",{"id":13},"intro","Intro",[16,17,18],"p",{},"「おい、今年立てた目標はなんだったか覚えているか？」",[16,20,21],{},"「覚えています。技術記事を週一ペースで更新することです...。」",[16,23,24],{},"「この記事は何本目だ？」",[16,26,27],{},"「...一本目です。」",[16,29,30],{},"「もうマクドナルドから『てりたま』が発売される季節だぞ？そもそも君は去年もそのような目標を立ててなかったか？」",[16,32,33,34,37],{},"「...はい。」",[35,36],"br",{},"\n「今年こそはやり遂げようと思ってたんですが、年始から仕事やプライベートでバタバタしていまして、気がついたらこんな時期まで何も記事を書けていませんでした...。」",[16,39,40],{},"師匠はため息をついた",[16,42,43],{},"「そうやって言い訳ばかり上手くなって。そんなんじゃいつになっても技術力が上がらないままだぞ。」",[16,45,46],{},"「...はい。おっしゃる通りです。」",[16,48,49],{},"「やれ」",[16,51,52],{},"「yes sir.」",[11,54,56],{"id":55},"overview","Overview",[16,58,59],{},"表題の通り本記事では、Nuxt Content で作ったブログに予約投稿機能を実装していきます。",[16,61,62],{},"Nuxt Content でのブログ作成については以下の記事をご覧ください。",[64,65,69],"callout",{"color":66,"icon":67,"to":68},"primary","ic:baseline-article","/tech/nuxt-content-v3-blog",[16,70,71],{},"Nuxt Content v3 + Nuxt Hub を使って爆速で個人ブログを作って公開する",[16,73,74],{},"まずは全体像から。",[76,77,78],"h3",{"id":78},"ディレクトリ構造",[16,80,81],{},"ディレクトリ構成と、それぞれの責務です。",[83,84,89],"pre",{"className":85,"code":87,"language":88},[86],"language-text","root/\n├ app\n│ ├ composables // フロント プレゼン層\n│ │ └ article\n│ │   └ index.ts\n│ └ pages\n│   └ [slug]\n│     └ index.vue\n├ content // Contents 記事を管理する\n│ └ articles\n│   └ *.md\n├ server \n│ ├ api // HTTP プレゼン層\n│ │ └ articles\n│ │   ├ [slug]\n│ │   │ └ index.get.ts // 記事詳細取得\n│ │   └ index.get.ts // 記事一覧取得\n│ └ domains\n│   ├ models // ドメイン層（Articleの概念）\n│   │ └ article\n│   │   └ index.ts\n│   └ repositories // レポジトリ層（データアクセスを抽象化する）\n│     └ article\n│       └ index.ts\n└ content.config.ts\n","text",[90,91,87],"code",{"__ignoreMap":92},"",[76,94,95],{"id":95},"方針",[16,97,98],{},"ディレクトリ構造から自明ですが、DDDに沿って実装していきます。",[16,100,101],{},"また、時刻を扱うためクライアントではなくサーバー側で記事をフィルターしていきます。",[16,103,104,105,109],{},"「",[106,107,108],"strong",{},"Nuxt Content のデータを Nuxt Server にて現在時刻をみてフィルターし、それを Composables で取得して利用する","」という流れで進めていきます。",[11,111,113],{"id":112},"collection","Collection",[16,115,116,117,120],{},"まずは ",[90,118,119],{},"content.config"," のコレクション定義から",[83,122,127],{"className":123,"code":124,"filename":125,"language":126,"meta":92,"style":92},"language-ts shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","export default defineContentConfig({\n  collections: {\n    articles: defineCollection({\n      type: 'page',\n      source: 'articles/*.md',\n      schema: z.object({\n        title: z.string(),\n        description: z.string(),\n        date: z.date(),\n        publishedAt: z.date().optional(), // 予約投稿はこの項目の設定日時を見る\n      })\n    })\n  }\n})\n","content.config.ts","ts",[90,128,129,153,167,183,205,222,243,263,281,300,330,339,347,353],{"__ignoreMap":92},[130,131,134,138,141,145,149],"span",{"class":132,"line":133},"line",1,[130,135,137],{"class":136},"stP2V","export",[130,139,140],{"class":136}," default",[130,142,144],{"class":143},"s7KVs"," defineContentConfig",[130,146,148],{"class":147},"sipQf","(",[130,150,152],{"class":151},"sfFde","{\n",[130,154,156,160,164],{"class":132,"line":155},2,[130,157,159],{"class":158},"sLCpo","  collections",[130,161,163],{"class":162},"seLpV",":",[130,165,166],{"class":162}," {\n",[130,168,170,173,175,178,181],{"class":132,"line":169},3,[130,171,172],{"class":158},"    articles",[130,174,163],{"class":162},[130,176,177],{"class":143}," defineCollection",[130,179,148],{"class":180},"sdyPO",[130,182,152],{"class":162},[130,184,186,189,191,195,199,202],{"class":132,"line":185},4,[130,187,188],{"class":158},"      type",[130,190,163],{"class":162},[130,192,194],{"class":193},"sPUPB"," '",[130,196,198],{"class":197},"sSIes","page",[130,200,201],{"class":193},"'",[130,203,204],{"class":162},",\n",[130,206,208,211,213,215,218,220],{"class":132,"line":207},5,[130,209,210],{"class":158},"      source",[130,212,163],{"class":162},[130,214,194],{"class":193},[130,216,217],{"class":197},"articles/*.md",[130,219,201],{"class":193},[130,221,204],{"class":162},[130,223,225,228,230,233,236,239,241],{"class":132,"line":224},6,[130,226,227],{"class":158},"      schema",[130,229,163],{"class":162},[130,231,232],{"class":180}," z",[130,234,235],{"class":162},".",[130,237,238],{"class":143},"object",[130,240,148],{"class":180},[130,242,152],{"class":162},[130,244,246,249,251,253,255,258,261],{"class":132,"line":245},7,[130,247,248],{"class":158},"        title",[130,250,163],{"class":162},[130,252,232],{"class":180},[130,254,235],{"class":162},[130,256,257],{"class":143},"string",[130,259,260],{"class":180},"()",[130,262,204],{"class":162},[130,264,266,269,271,273,275,277,279],{"class":132,"line":265},8,[130,267,268],{"class":158},"        description",[130,270,163],{"class":162},[130,272,232],{"class":180},[130,274,235],{"class":162},[130,276,257],{"class":143},[130,278,260],{"class":180},[130,280,204],{"class":162},[130,282,284,287,289,291,293,296,298],{"class":132,"line":283},9,[130,285,286],{"class":158},"        date",[130,288,163],{"class":162},[130,290,232],{"class":180},[130,292,235],{"class":162},[130,294,295],{"class":143},"date",[130,297,260],{"class":180},[130,299,204],{"class":162},[130,301,303,306,308,310,312,314,316,318,321,323,326],{"class":132,"line":302},10,[130,304,305],{"class":158},"        publishedAt",[130,307,163],{"class":162},[130,309,232],{"class":180},[130,311,235],{"class":162},[130,313,295],{"class":143},[130,315,260],{"class":180},[130,317,235],{"class":162},[130,319,320],{"class":143},"optional",[130,322,260],{"class":180},[130,324,325],{"class":162},",",[130,327,329],{"class":328},"sZPSj"," // 予約投稿はこの項目の設定日時を見る\n",[130,331,333,336],{"class":132,"line":332},11,[130,334,335],{"class":162},"      }",[130,337,338],{"class":180},")\n",[130,340,342,345],{"class":132,"line":341},12,[130,343,344],{"class":162},"    }",[130,346,338],{"class":180},[130,348,350],{"class":132,"line":349},13,[130,351,352],{"class":162},"  }\n",[130,354,356,359],{"class":132,"line":355},14,[130,357,358],{"class":151},"}",[130,360,338],{"class":147},[16,362,363,366,367,369],{},[90,364,365],{},"publishedAt"," はオプショナルにしました（既存の公開済みの記事全てに ",[90,368,365],{}," を、設定するのは面倒だったので）が、その辺は都合の良いように設定してください。",[371,372],"hr",{},[16,374,375],{},"次にテスト用に何記事か追加していきます。",[83,377,382],{"className":378,"code":379,"filename":380,"language":381,"meta":92,"style":92},"language-md shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","---\ntitle: 公開済みテスト記事\ndescritption: 公開済みのテスト記事です\ndate: 2026-03-01\npublishedAt: 2026-03-01 08:00\n---\n\n公開済みテスト記事です\n\n","~~/content/articles/hoge.md","md",[90,383,384,390,395,400,405,410,415,421],{"__ignoreMap":92},[130,385,386],{"class":132,"line":133},[130,387,389],{"class":388},"sDE9X","---\n",[130,391,392],{"class":132,"line":155},[130,393,394],{"class":180},"title: 公開済みテスト記事\n",[130,396,397],{"class":132,"line":169},[130,398,399],{"class":180},"descritption: 公開済みのテスト記事です\n",[130,401,402],{"class":132,"line":185},[130,403,404],{"class":180},"date: 2026-03-01\n",[130,406,407],{"class":132,"line":207},[130,408,409],{"class":180},"publishedAt: 2026-03-01 08:00\n",[130,411,412],{"class":132,"line":224},[130,413,389],{"class":414},"sdaUG",[130,416,417],{"class":132,"line":245},[130,418,420],{"emptyLinePlaceholder":419},true,"\n",[130,422,423],{"class":132,"line":265},[130,424,425],{"class":180},"公開済みテスト記事です\n",[83,427,430],{"className":378,"code":428,"filename":429,"language":381,"meta":92,"style":92},"---\ntitle: 公開前テスト記事\ndescritption: 公開前のテスト記事です\ndate: 2026-03-02\npublishedAt: 2026-03-02 08:00\n---\n\n公開前テスト記事です。\n","~~/content/articles/fuga.md",[90,431,432,436,441,446,451,456,460,464],{"__ignoreMap":92},[130,433,434],{"class":132,"line":133},[130,435,389],{"class":388},[130,437,438],{"class":132,"line":155},[130,439,440],{"class":180},"title: 公開前テスト記事\n",[130,442,443],{"class":132,"line":169},[130,444,445],{"class":180},"descritption: 公開前のテスト記事です\n",[130,447,448],{"class":132,"line":185},[130,449,450],{"class":180},"date: 2026-03-02\n",[130,452,453],{"class":132,"line":207},[130,454,455],{"class":180},"publishedAt: 2026-03-02 08:00\n",[130,457,458],{"class":132,"line":224},[130,459,389],{"class":414},[130,461,462],{"class":132,"line":245},[130,463,420],{"emptyLinePlaceholder":419},[130,465,466],{"class":132,"line":265},[130,467,468],{"class":180},"公開前テスト記事です。\n",[11,470,472],{"id":471},"nuxt-server","Nuxt Server",[16,474,475],{},"サーバー側にて Nuxt Content からを記事取得し、公開済み記事をフィルターしていきます。",[76,477,479],{"id":478},"repository","Repository",[16,481,482],{},"Repository では、外部リソース（今回は Nuxt Content）からのデータアクセスを抽象化します。",[83,484,487],{"className":123,"code":485,"filename":486,"language":126,"meta":92,"style":92},"import type { H3Event } from 'h3'\nimport { queryCollection } from '@nuxt/content/server'\n\nexport const findArticleBySlug = async (event: H3Event, slug: string) => {\n  const article = await queryCollection\u003C'articles'>(event, 'articles')\n    .path(`/articles/${slug}`)\n    .first()\n\n  return article\n}\n\nexport const findArticles = async (event: H3Event) => {\n  const articles = await queryCollection\u003C'articles'>(event, 'articles')\n    .order('date', 'DESC')\n    .all()\n\n  return articles\n}\n","~~/server/domains/repositories/article/index.ts",[90,488,489,516,536,540,590,633,660,670,674,682,687,691,718,755,781,791,796,804],{"__ignoreMap":92},[130,490,491,494,497,500,503,506,509,511,513],{"class":132,"line":133},[130,492,493],{"class":136},"import",[130,495,496],{"class":136}," type",[130,498,499],{"class":162}," {",[130,501,502],{"class":180}," H3Event",[130,504,505],{"class":162}," }",[130,507,508],{"class":136}," from",[130,510,194],{"class":193},[130,512,76],{"class":197},[130,514,515],{"class":193},"'\n",[130,517,518,520,522,525,527,529,531,534],{"class":132,"line":155},[130,519,493],{"class":136},[130,521,499],{"class":162},[130,523,524],{"class":180}," queryCollection",[130,526,505],{"class":162},[130,528,508],{"class":136},[130,530,194],{"class":193},[130,532,533],{"class":197},"@nuxt/content/server",[130,535,515],{"class":193},[130,537,538],{"class":132,"line":169},[130,539,420],{"emptyLinePlaceholder":419},[130,541,542,544,548,552,556,559,562,566,568,571,573,576,578,582,585,588],{"class":132,"line":185},[130,543,137],{"class":136},[130,545,547],{"class":546},"sGRfs"," const",[130,549,551],{"class":550},"s8Xov"," findArticleBySlug",[130,553,555],{"class":554},"sUBcA"," =",[130,557,558],{"class":546}," async",[130,560,561],{"class":162}," (",[130,563,565],{"class":564},"senS2","event",[130,567,163],{"class":554},[130,569,502],{"class":570},"sywW5",[130,572,325],{"class":162},[130,574,575],{"class":564}," slug",[130,577,163],{"class":554},[130,579,581],{"class":580},"snYqn"," string",[130,583,584],{"class":162},")",[130,586,587],{"class":546}," =>",[130,589,166],{"class":162},[130,591,592,595,599,601,604,606,609,611,614,616,619,621,623,625,627,629,631],{"class":132,"line":207},[130,593,594],{"class":546},"  const",[130,596,598],{"class":597},"sSuNx"," article",[130,600,555],{"class":554},[130,602,603],{"class":136}," await",[130,605,524],{"class":143},[130,607,608],{"class":162},"\u003C",[130,610,201],{"class":193},[130,612,613],{"class":197},"articles",[130,615,201],{"class":193},[130,617,618],{"class":162},">",[130,620,148],{"class":158},[130,622,565],{"class":180},[130,624,325],{"class":162},[130,626,194],{"class":193},[130,628,613],{"class":197},[130,630,201],{"class":193},[130,632,338],{"class":158},[130,634,635,638,641,643,646,649,652,655,658],{"class":132,"line":224},[130,636,637],{"class":162},"    .",[130,639,640],{"class":143},"path",[130,642,148],{"class":158},[130,644,645],{"class":193},"`",[130,647,648],{"class":197},"/articles/",[130,650,651],{"class":193},"${",[130,653,654],{"class":180},"slug",[130,656,657],{"class":193},"}`",[130,659,338],{"class":158},[130,661,662,664,667],{"class":132,"line":245},[130,663,637],{"class":162},[130,665,666],{"class":143},"first",[130,668,669],{"class":158},"()\n",[130,671,672],{"class":132,"line":265},[130,673,420],{"emptyLinePlaceholder":419},[130,675,676,679],{"class":132,"line":283},[130,677,678],{"class":136},"  return",[130,680,681],{"class":180}," article\n",[130,683,684],{"class":132,"line":302},[130,685,686],{"class":162},"}\n",[130,688,689],{"class":132,"line":332},[130,690,420],{"emptyLinePlaceholder":419},[130,692,693,695,697,700,702,704,706,708,710,712,714,716],{"class":132,"line":341},[130,694,137],{"class":136},[130,696,547],{"class":546},[130,698,699],{"class":550}," findArticles",[130,701,555],{"class":554},[130,703,558],{"class":546},[130,705,561],{"class":162},[130,707,565],{"class":564},[130,709,163],{"class":554},[130,711,502],{"class":570},[130,713,584],{"class":162},[130,715,587],{"class":546},[130,717,166],{"class":162},[130,719,720,722,725,727,729,731,733,735,737,739,741,743,745,747,749,751,753],{"class":132,"line":349},[130,721,594],{"class":546},[130,723,724],{"class":597}," articles",[130,726,555],{"class":554},[130,728,603],{"class":136},[130,730,524],{"class":143},[130,732,608],{"class":162},[130,734,201],{"class":193},[130,736,613],{"class":197},[130,738,201],{"class":193},[130,740,618],{"class":162},[130,742,148],{"class":158},[130,744,565],{"class":180},[130,746,325],{"class":162},[130,748,194],{"class":193},[130,750,613],{"class":197},[130,752,201],{"class":193},[130,754,338],{"class":158},[130,756,757,759,762,764,766,768,770,772,774,777,779],{"class":132,"line":355},[130,758,637],{"class":162},[130,760,761],{"class":143},"order",[130,763,148],{"class":158},[130,765,201],{"class":193},[130,767,295],{"class":197},[130,769,201],{"class":193},[130,771,325],{"class":162},[130,773,194],{"class":193},[130,775,776],{"class":197},"DESC",[130,778,201],{"class":193},[130,780,338],{"class":158},[130,782,784,786,789],{"class":132,"line":783},15,[130,785,637],{"class":162},[130,787,788],{"class":143},"all",[130,790,669],{"class":158},[130,792,794],{"class":132,"line":793},16,[130,795,420],{"emptyLinePlaceholder":419},[130,797,799,801],{"class":132,"line":798},17,[130,800,678],{"class":136},[130,802,803],{"class":180}," articles\n",[130,805,807],{"class":132,"line":806},18,[130,808,686],{"class":162},[16,810,811,812,815],{},"最初は、",[90,813,814],{},"queryCollection"," の where句 にて公開日時の絞り込みを行おうと考えていたのですが、日付の比較までで時刻までは比較できなそうだったのと、単一記事では where できなそうだたりで少々都合が悪かったので、モデル層にてフィルターを行うよう実装しました。",[76,817,819],{"id":818},"model","Model",[16,821,822],{},"Models では、Repository から取得したデータをドメインモデルに変換し、ビジネスロジックを提供します。",[16,824,825,826,828],{},"今回は、公開前の記事をフィルターする処理を行います。",[35,827],{},"\n日時の比較に Day.js を使用するので各自インストールお願いします。",[83,830,833],{"className":123,"code":831,"filename":832,"language":126,"meta":92,"style":92},"import type { H3Event } from 'h3'\nimport type { ArticleCollectionItem } from '@nuxt/content'\nimport dayjs from 'dayjs/esm'\nimport utc from 'dayjs/esm/plugin/utc'\nimport timezone from 'dayjs/esm/plugin/timezone'\nimport isSameOrAfter from 'dayjs/esm/plugin/isSameOrAfter'\nimport { findArticleBySlug, findArticles } from '~~/server/domains/repositories/article'\n\ndayjs.extend(utc)\ndayjs.extend(timezone)\ndayjs.extend(isSameOrAfter)\n\nconst TIME_ZONE = 'Asia/Tokyo'\n\n/**\n * 記事スラッグをもとに単一の公開記事を取得する\n * @param event H3Event\n * @param slug 記事スラッグ\n * @returns 公開記事 Get\n */\nexport const getArticle = async (event: H3Event, slug: string) => {\n  const article = await findArticleBySlug(event, slug)\n\n  if (article === null) {\n    return null\n  }\n\n  return filterPublishedArticle(article) ? article : null\n}\n\n/**\n * 公開記事の一覧を取得する\n * @param event H3Event\n * @returns 公開済み記事 List\n */\nexport const getArticles = async (event: H3Event) => {\n  const articles = await findArticles(event)\n\n  return articles.filter(filterPublishedArticle)\n}\n\n/**\n * 公開記事フィルター\n * @param article ArticleCollectionItem\n * @returns boolean\n */\nconst filterPublishedArticle = (article: ArticleCollectionItem) => {\n  // 公開日時が設定されていなければ公開済みとして扱う\n  if (!article.publishedAt) {\n    return true\n  }\n\n  const now = dayjs().tz(TIME_ZONE)\n  const publishedAt = dayjs.tz(\n    article.publishedAt,\n    TIME_ZONE,\n  )\n\n  // publishedAt が現在時刻以降か判定する\n  return now.isSameOrAfter(publishedAt)\n}\n","~~/server/domains/models/article/index.ts",[90,834,835,855,877,894,910,926,942,965,969,982,993,1004,1008,1025,1029,1034,1039,1058,1071,1084,1090,1126,1149,1154,1177,1186,1191,1196,1220,1225,1230,1235,1241,1254,1266,1271,1299,1318,1323,1342,1347,1352,1357,1363,1377,1389,1394,1417,1423,1443,1452,1457,1462,1489,1508,1520,1528,1534,1539,1545,1563],{"__ignoreMap":92},[130,836,837,839,841,843,845,847,849,851,853],{"class":132,"line":133},[130,838,493],{"class":136},[130,840,496],{"class":136},[130,842,499],{"class":162},[130,844,502],{"class":180},[130,846,505],{"class":162},[130,848,508],{"class":136},[130,850,194],{"class":193},[130,852,76],{"class":197},[130,854,515],{"class":193},[130,856,857,859,861,863,866,868,870,872,875],{"class":132,"line":155},[130,858,493],{"class":136},[130,860,496],{"class":136},[130,862,499],{"class":162},[130,864,865],{"class":180}," ArticleCollectionItem",[130,867,505],{"class":162},[130,869,508],{"class":136},[130,871,194],{"class":193},[130,873,874],{"class":197},"@nuxt/content",[130,876,515],{"class":193},[130,878,879,881,884,887,889,892],{"class":132,"line":169},[130,880,493],{"class":136},[130,882,883],{"class":180}," dayjs ",[130,885,886],{"class":136},"from",[130,888,194],{"class":193},[130,890,891],{"class":197},"dayjs/esm",[130,893,515],{"class":193},[130,895,896,898,901,903,905,908],{"class":132,"line":185},[130,897,493],{"class":136},[130,899,900],{"class":180}," utc ",[130,902,886],{"class":136},[130,904,194],{"class":193},[130,906,907],{"class":197},"dayjs/esm/plugin/utc",[130,909,515],{"class":193},[130,911,912,914,917,919,921,924],{"class":132,"line":207},[130,913,493],{"class":136},[130,915,916],{"class":180}," timezone ",[130,918,886],{"class":136},[130,920,194],{"class":193},[130,922,923],{"class":197},"dayjs/esm/plugin/timezone",[130,925,515],{"class":193},[130,927,928,930,933,935,937,940],{"class":132,"line":224},[130,929,493],{"class":136},[130,931,932],{"class":180}," isSameOrAfter ",[130,934,886],{"class":136},[130,936,194],{"class":193},[130,938,939],{"class":197},"dayjs/esm/plugin/isSameOrAfter",[130,941,515],{"class":193},[130,943,944,946,948,950,952,954,956,958,960,963],{"class":132,"line":245},[130,945,493],{"class":136},[130,947,499],{"class":162},[130,949,551],{"class":180},[130,951,325],{"class":162},[130,953,699],{"class":180},[130,955,505],{"class":162},[130,957,508],{"class":136},[130,959,194],{"class":193},[130,961,962],{"class":197},"~~/server/domains/repositories/article",[130,964,515],{"class":193},[130,966,967],{"class":132,"line":265},[130,968,420],{"emptyLinePlaceholder":419},[130,970,971,974,976,979],{"class":132,"line":283},[130,972,973],{"class":180},"dayjs",[130,975,235],{"class":162},[130,977,978],{"class":143},"extend",[130,980,981],{"class":180},"(utc)\n",[130,983,984,986,988,990],{"class":132,"line":302},[130,985,973],{"class":180},[130,987,235],{"class":162},[130,989,978],{"class":143},[130,991,992],{"class":180},"(timezone)\n",[130,994,995,997,999,1001],{"class":132,"line":332},[130,996,973],{"class":180},[130,998,235],{"class":162},[130,1000,978],{"class":143},[130,1002,1003],{"class":180},"(isSameOrAfter)\n",[130,1005,1006],{"class":132,"line":341},[130,1007,420],{"emptyLinePlaceholder":419},[130,1009,1010,1013,1016,1018,1020,1023],{"class":132,"line":349},[130,1011,1012],{"class":546},"const",[130,1014,1015],{"class":597}," TIME_ZONE",[130,1017,555],{"class":554},[130,1019,194],{"class":193},[130,1021,1022],{"class":197},"Asia/Tokyo",[130,1024,515],{"class":193},[130,1026,1027],{"class":132,"line":355},[130,1028,420],{"emptyLinePlaceholder":419},[130,1030,1031],{"class":132,"line":783},[130,1032,1033],{"class":328},"/**\n",[130,1035,1036],{"class":132,"line":793},[130,1037,1038],{"class":328}," * 記事スラッグをもとに単一の公開記事を取得する\n",[130,1040,1041,1044,1047,1051,1055],{"class":132,"line":798},[130,1042,1043],{"class":328}," * ",[130,1045,1046],{"class":136},"@",[130,1048,1050],{"class":1049},"sST-Y","param",[130,1052,1054],{"class":1053},"sm6hg"," event",[130,1056,1057],{"class":328}," H3Event\n",[130,1059,1060,1062,1064,1066,1068],{"class":132,"line":806},[130,1061,1043],{"class":328},[130,1063,1046],{"class":136},[130,1065,1050],{"class":1049},[130,1067,575],{"class":1053},[130,1069,1070],{"class":328}," 記事スラッグ\n",[130,1072,1074,1076,1078,1081],{"class":132,"line":1073},19,[130,1075,1043],{"class":328},[130,1077,1046],{"class":136},[130,1079,1080],{"class":1049},"returns",[130,1082,1083],{"class":328}," 公開記事 Get\n",[130,1085,1087],{"class":132,"line":1086},20,[130,1088,1089],{"class":328}," */\n",[130,1091,1093,1095,1097,1100,1102,1104,1106,1108,1110,1112,1114,1116,1118,1120,1122,1124],{"class":132,"line":1092},21,[130,1094,137],{"class":136},[130,1096,547],{"class":546},[130,1098,1099],{"class":550}," getArticle",[130,1101,555],{"class":554},[130,1103,558],{"class":546},[130,1105,561],{"class":162},[130,1107,565],{"class":564},[130,1109,163],{"class":554},[130,1111,502],{"class":570},[130,1113,325],{"class":162},[130,1115,575],{"class":564},[130,1117,163],{"class":554},[130,1119,581],{"class":580},[130,1121,584],{"class":162},[130,1123,587],{"class":546},[130,1125,166],{"class":162},[130,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147],{"class":132,"line":1128},22,[130,1130,594],{"class":546},[130,1132,598],{"class":597},[130,1134,555],{"class":554},[130,1136,603],{"class":136},[130,1138,551],{"class":143},[130,1140,148],{"class":158},[130,1142,565],{"class":180},[130,1144,325],{"class":162},[130,1146,575],{"class":180},[130,1148,338],{"class":158},[130,1150,1152],{"class":132,"line":1151},23,[130,1153,420],{"emptyLinePlaceholder":419},[130,1155,1157,1160,1162,1165,1168,1172,1175],{"class":132,"line":1156},24,[130,1158,1159],{"class":136},"  if",[130,1161,561],{"class":158},[130,1163,1164],{"class":180},"article",[130,1166,1167],{"class":554}," ===",[130,1169,1171],{"class":1170},"s4Pz2"," null",[130,1173,1174],{"class":158},") ",[130,1176,152],{"class":162},[130,1178,1180,1183],{"class":132,"line":1179},25,[130,1181,1182],{"class":136},"    return",[130,1184,1185],{"class":1170}," null\n",[130,1187,1189],{"class":132,"line":1188},26,[130,1190,352],{"class":162},[130,1192,1194],{"class":132,"line":1193},27,[130,1195,420],{"emptyLinePlaceholder":419},[130,1197,1199,1201,1204,1206,1208,1210,1213,1215,1218],{"class":132,"line":1198},28,[130,1200,678],{"class":136},[130,1202,1203],{"class":143}," filterPublishedArticle",[130,1205,148],{"class":158},[130,1207,1164],{"class":180},[130,1209,1174],{"class":158},[130,1211,1212],{"class":554},"?",[130,1214,598],{"class":180},[130,1216,1217],{"class":554}," :",[130,1219,1185],{"class":1170},[130,1221,1223],{"class":132,"line":1222},29,[130,1224,686],{"class":162},[130,1226,1228],{"class":132,"line":1227},30,[130,1229,420],{"emptyLinePlaceholder":419},[130,1231,1233],{"class":132,"line":1232},31,[130,1234,1033],{"class":328},[130,1236,1238],{"class":132,"line":1237},32,[130,1239,1240],{"class":328}," * 公開記事の一覧を取得する\n",[130,1242,1244,1246,1248,1250,1252],{"class":132,"line":1243},33,[130,1245,1043],{"class":328},[130,1247,1046],{"class":136},[130,1249,1050],{"class":1049},[130,1251,1054],{"class":1053},[130,1253,1057],{"class":328},[130,1255,1257,1259,1261,1263],{"class":132,"line":1256},34,[130,1258,1043],{"class":328},[130,1260,1046],{"class":136},[130,1262,1080],{"class":1049},[130,1264,1265],{"class":328}," 公開済み記事 List\n",[130,1267,1269],{"class":132,"line":1268},35,[130,1270,1089],{"class":328},[130,1272,1274,1276,1278,1281,1283,1285,1287,1289,1291,1293,1295,1297],{"class":132,"line":1273},36,[130,1275,137],{"class":136},[130,1277,547],{"class":546},[130,1279,1280],{"class":550}," getArticles",[130,1282,555],{"class":554},[130,1284,558],{"class":546},[130,1286,561],{"class":162},[130,1288,565],{"class":564},[130,1290,163],{"class":554},[130,1292,502],{"class":570},[130,1294,584],{"class":162},[130,1296,587],{"class":546},[130,1298,166],{"class":162},[130,1300,1302,1304,1306,1308,1310,1312,1314,1316],{"class":132,"line":1301},37,[130,1303,594],{"class":546},[130,1305,724],{"class":597},[130,1307,555],{"class":554},[130,1309,603],{"class":136},[130,1311,699],{"class":143},[130,1313,148],{"class":158},[130,1315,565],{"class":180},[130,1317,338],{"class":158},[130,1319,1321],{"class":132,"line":1320},38,[130,1322,420],{"emptyLinePlaceholder":419},[130,1324,1326,1328,1330,1332,1335,1337,1340],{"class":132,"line":1325},39,[130,1327,678],{"class":136},[130,1329,724],{"class":180},[130,1331,235],{"class":162},[130,1333,1334],{"class":143},"filter",[130,1336,148],{"class":158},[130,1338,1339],{"class":180},"filterPublishedArticle",[130,1341,338],{"class":158},[130,1343,1345],{"class":132,"line":1344},40,[130,1346,686],{"class":162},[130,1348,1350],{"class":132,"line":1349},41,[130,1351,420],{"emptyLinePlaceholder":419},[130,1353,1355],{"class":132,"line":1354},42,[130,1356,1033],{"class":328},[130,1358,1360],{"class":132,"line":1359},43,[130,1361,1362],{"class":328}," * 公開記事フィルター\n",[130,1364,1366,1368,1370,1372,1374],{"class":132,"line":1365},44,[130,1367,1043],{"class":328},[130,1369,1046],{"class":136},[130,1371,1050],{"class":1049},[130,1373,598],{"class":1053},[130,1375,1376],{"class":328}," ArticleCollectionItem\n",[130,1378,1380,1382,1384,1386],{"class":132,"line":1379},45,[130,1381,1043],{"class":328},[130,1383,1046],{"class":136},[130,1385,1080],{"class":1049},[130,1387,1388],{"class":328}," boolean\n",[130,1390,1392],{"class":132,"line":1391},46,[130,1393,1089],{"class":328},[130,1395,1397,1399,1401,1403,1405,1407,1409,1411,1413,1415],{"class":132,"line":1396},47,[130,1398,1012],{"class":546},[130,1400,1203],{"class":550},[130,1402,555],{"class":554},[130,1404,561],{"class":162},[130,1406,1164],{"class":564},[130,1408,163],{"class":554},[130,1410,865],{"class":570},[130,1412,584],{"class":162},[130,1414,587],{"class":546},[130,1416,166],{"class":162},[130,1418,1420],{"class":132,"line":1419},48,[130,1421,1422],{"class":328},"  // 公開日時が設定されていなければ公開済みとして扱う\n",[130,1424,1426,1428,1430,1433,1435,1437,1439,1441],{"class":132,"line":1425},49,[130,1427,1159],{"class":136},[130,1429,561],{"class":158},[130,1431,1432],{"class":554},"!",[130,1434,1164],{"class":180},[130,1436,235],{"class":162},[130,1438,365],{"class":180},[130,1440,1174],{"class":158},[130,1442,152],{"class":162},[130,1444,1446,1448],{"class":132,"line":1445},50,[130,1447,1182],{"class":136},[130,1449,1451],{"class":1450},"sBxIE"," true\n",[130,1453,1455],{"class":132,"line":1454},51,[130,1456,352],{"class":162},[130,1458,1460],{"class":132,"line":1459},52,[130,1461,420],{"emptyLinePlaceholder":419},[130,1463,1465,1467,1470,1472,1475,1477,1479,1482,1484,1487],{"class":132,"line":1464},53,[130,1466,594],{"class":546},[130,1468,1469],{"class":597}," now",[130,1471,555],{"class":554},[130,1473,1474],{"class":143}," dayjs",[130,1476,260],{"class":158},[130,1478,235],{"class":162},[130,1480,1481],{"class":143},"tz",[130,1483,148],{"class":158},[130,1485,1486],{"class":597},"TIME_ZONE",[130,1488,338],{"class":158},[130,1490,1492,1494,1497,1499,1501,1503,1505],{"class":132,"line":1491},54,[130,1493,594],{"class":546},[130,1495,1496],{"class":597}," publishedAt",[130,1498,555],{"class":554},[130,1500,1474],{"class":180},[130,1502,235],{"class":162},[130,1504,1481],{"class":143},[130,1506,1507],{"class":158},"(\n",[130,1509,1511,1514,1516,1518],{"class":132,"line":1510},55,[130,1512,1513],{"class":180},"    article",[130,1515,235],{"class":162},[130,1517,365],{"class":180},[130,1519,204],{"class":162},[130,1521,1523,1526],{"class":132,"line":1522},56,[130,1524,1525],{"class":597},"    TIME_ZONE",[130,1527,204],{"class":162},[130,1529,1531],{"class":132,"line":1530},57,[130,1532,1533],{"class":158},"  )\n",[130,1535,1537],{"class":132,"line":1536},58,[130,1538,420],{"emptyLinePlaceholder":419},[130,1540,1542],{"class":132,"line":1541},59,[130,1543,1544],{"class":328},"  // publishedAt が現在時刻以降か判定する\n",[130,1546,1548,1550,1552,1554,1557,1559,1561],{"class":132,"line":1547},60,[130,1549,678],{"class":136},[130,1551,1469],{"class":180},[130,1553,235],{"class":162},[130,1555,1556],{"class":143},"isSameOrAfter",[130,1558,148],{"class":158},[130,1560,365],{"class":180},[130,1562,338],{"class":158},[130,1564,1566],{"class":132,"line":1565},61,[130,1567,686],{"class":162},[76,1569,1571],{"id":1570},"api-handler","API Handler",[16,1573,1574],{},"一覧と詳細用に List と Get API ハンドラーを用意します。",[1576,1577,1579],"h4",{"id":1578},"list-api","List API",[83,1581,1584],{"className":123,"code":1582,"filename":1583,"language":126,"meta":92,"style":92},"import { getArticles } from '~~/server/domains/models/article'\n\nexport default defineEventHandler(async (event) => {\n  const articles = await getArticles(event)\n\n  return articles\n})\n","~~/server/api/articles/index.get.ts",[90,1585,1586,1605,1609,1633,1651,1655,1661],{"__ignoreMap":92},[130,1587,1588,1590,1592,1594,1596,1598,1600,1603],{"class":132,"line":133},[130,1589,493],{"class":136},[130,1591,499],{"class":162},[130,1593,1280],{"class":180},[130,1595,505],{"class":162},[130,1597,508],{"class":136},[130,1599,194],{"class":193},[130,1601,1602],{"class":197},"~~/server/domains/models/article",[130,1604,515],{"class":193},[130,1606,1607],{"class":132,"line":155},[130,1608,420],{"emptyLinePlaceholder":419},[130,1610,1611,1613,1615,1618,1620,1623,1625,1627,1629,1631],{"class":132,"line":169},[130,1612,137],{"class":136},[130,1614,140],{"class":136},[130,1616,1617],{"class":143}," defineEventHandler",[130,1619,148],{"class":147},[130,1621,1622],{"class":546},"async",[130,1624,561],{"class":151},[130,1626,565],{"class":564},[130,1628,584],{"class":151},[130,1630,587],{"class":546},[130,1632,166],{"class":162},[130,1634,1635,1637,1639,1641,1643,1645,1647,1649],{"class":132,"line":185},[130,1636,594],{"class":546},[130,1638,724],{"class":597},[130,1640,555],{"class":554},[130,1642,603],{"class":136},[130,1644,1280],{"class":143},[130,1646,148],{"class":158},[130,1648,565],{"class":180},[130,1650,338],{"class":158},[130,1652,1653],{"class":132,"line":207},[130,1654,420],{"emptyLinePlaceholder":419},[130,1656,1657,1659],{"class":132,"line":224},[130,1658,678],{"class":136},[130,1660,803],{"class":180},[130,1662,1663,1665],{"class":132,"line":245},[130,1664,358],{"class":162},[130,1666,338],{"class":147},[1576,1668,1670],{"id":1669},"get-api","Get API",[83,1672,1675],{"className":123,"code":1673,"filename":1674,"language":126,"meta":92,"style":92},"import { z } from 'zod'\nimport { getArticle } from '~~/server/domains/models/article'\n\nconst PARAMETER_SCHEMA = z.object({\n  slug: z.string(),\n})\n\nexport default defineEventHandler(async (event) => {\n  const { slug } = await getValidatedRouterParams(event, PARAMETER_SCHEMA.parse)\n\n  const article = await getArticle(event, slug)\n\n  return article\n})\n","~~/server/api/articles/[slug]/index.get.ts",[90,1676,1677,1696,1714,1718,1737,1754,1760,1764,1786,1818,1822,1844,1848,1854],{"__ignoreMap":92},[130,1678,1679,1681,1683,1685,1687,1689,1691,1694],{"class":132,"line":133},[130,1680,493],{"class":136},[130,1682,499],{"class":162},[130,1684,232],{"class":180},[130,1686,505],{"class":162},[130,1688,508],{"class":136},[130,1690,194],{"class":193},[130,1692,1693],{"class":197},"zod",[130,1695,515],{"class":193},[130,1697,1698,1700,1702,1704,1706,1708,1710,1712],{"class":132,"line":155},[130,1699,493],{"class":136},[130,1701,499],{"class":162},[130,1703,1099],{"class":180},[130,1705,505],{"class":162},[130,1707,508],{"class":136},[130,1709,194],{"class":193},[130,1711,1602],{"class":197},[130,1713,515],{"class":193},[130,1715,1716],{"class":132,"line":169},[130,1717,420],{"emptyLinePlaceholder":419},[130,1719,1720,1722,1725,1727,1729,1731,1733,1735],{"class":132,"line":185},[130,1721,1012],{"class":546},[130,1723,1724],{"class":597}," PARAMETER_SCHEMA",[130,1726,555],{"class":554},[130,1728,232],{"class":180},[130,1730,235],{"class":162},[130,1732,238],{"class":143},[130,1734,148],{"class":180},[130,1736,152],{"class":162},[130,1738,1739,1742,1744,1746,1748,1750,1752],{"class":132,"line":207},[130,1740,1741],{"class":158},"  slug",[130,1743,163],{"class":162},[130,1745,232],{"class":180},[130,1747,235],{"class":162},[130,1749,257],{"class":143},[130,1751,260],{"class":180},[130,1753,204],{"class":162},[130,1755,1756,1758],{"class":132,"line":224},[130,1757,358],{"class":162},[130,1759,338],{"class":180},[130,1761,1762],{"class":132,"line":245},[130,1763,420],{"emptyLinePlaceholder":419},[130,1765,1766,1768,1770,1772,1774,1776,1778,1780,1782,1784],{"class":132,"line":265},[130,1767,137],{"class":136},[130,1769,140],{"class":136},[130,1771,1617],{"class":143},[130,1773,148],{"class":147},[130,1775,1622],{"class":546},[130,1777,561],{"class":151},[130,1779,565],{"class":564},[130,1781,584],{"class":151},[130,1783,587],{"class":546},[130,1785,166],{"class":162},[130,1787,1788,1790,1792,1794,1796,1798,1800,1803,1805,1807,1809,1811,1813,1816],{"class":132,"line":283},[130,1789,594],{"class":546},[130,1791,499],{"class":162},[130,1793,575],{"class":597},[130,1795,505],{"class":162},[130,1797,555],{"class":554},[130,1799,603],{"class":136},[130,1801,1802],{"class":143}," getValidatedRouterParams",[130,1804,148],{"class":158},[130,1806,565],{"class":180},[130,1808,325],{"class":162},[130,1810,1724],{"class":597},[130,1812,235],{"class":162},[130,1814,1815],{"class":180},"parse",[130,1817,338],{"class":158},[130,1819,1820],{"class":132,"line":302},[130,1821,420],{"emptyLinePlaceholder":419},[130,1823,1824,1826,1828,1830,1832,1834,1836,1838,1840,1842],{"class":132,"line":332},[130,1825,594],{"class":546},[130,1827,598],{"class":597},[130,1829,555],{"class":554},[130,1831,603],{"class":136},[130,1833,1099],{"class":143},[130,1835,148],{"class":158},[130,1837,565],{"class":180},[130,1839,325],{"class":162},[130,1841,575],{"class":180},[130,1843,338],{"class":158},[130,1845,1846],{"class":132,"line":341},[130,1847,420],{"emptyLinePlaceholder":419},[130,1849,1850,1852],{"class":132,"line":349},[130,1851,678],{"class":136},[130,1853,681],{"class":180},[130,1855,1856,1858],{"class":132,"line":355},[130,1857,358],{"class":162},[130,1859,338],{"class":147},[16,1861,1862],{},"エンドポイントを叩いてみて、レスポンスが公開済み記事のみになっていればサーバー側の実装完了です。",[11,1864,1866],{"id":1865},"composables","Composables",[83,1868,1871],{"className":123,"code":1869,"filename":1870,"language":126,"meta":92,"style":92},"import type { ArticleCollectionItem } from '@nuxt/content'\n\nexport const useArticles = async () => {\n  const { data: articles } = await useFetch('/api/articles', {\n    default: (): ArticleCollectionItem[] => [],\n  })\n\n  return { articles }\n}\n\nexport const useArticle = async (path: string) => {\n  const { data: article } = await useFetch\u003CArticleCollectionItem | null>(`/api/articles/${path}`,\n    {\n      default: () => null,\n    }\n  )\n\n  return { article }\n}\n","~/app/composables/articles/index.ts",[90,1872,1873,1893,1897,1917,1953,1977,1984,1988,1999,2003,2007,2034,2081,2086,2101,2106,2110,2114,2124],{"__ignoreMap":92},[130,1874,1875,1877,1879,1881,1883,1885,1887,1889,1891],{"class":132,"line":133},[130,1876,493],{"class":136},[130,1878,496],{"class":136},[130,1880,499],{"class":162},[130,1882,865],{"class":180},[130,1884,505],{"class":162},[130,1886,508],{"class":136},[130,1888,194],{"class":193},[130,1890,874],{"class":197},[130,1892,515],{"class":193},[130,1894,1895],{"class":132,"line":155},[130,1896,420],{"emptyLinePlaceholder":419},[130,1898,1899,1901,1903,1906,1908,1910,1913,1915],{"class":132,"line":169},[130,1900,137],{"class":136},[130,1902,547],{"class":546},[130,1904,1905],{"class":550}," useArticles",[130,1907,555],{"class":554},[130,1909,558],{"class":546},[130,1911,1912],{"class":162}," ()",[130,1914,587],{"class":546},[130,1916,166],{"class":162},[130,1918,1919,1921,1923,1927,1929,1931,1933,1935,1937,1940,1942,1944,1947,1949,1951],{"class":132,"line":185},[130,1920,594],{"class":546},[130,1922,499],{"class":162},[130,1924,1926],{"class":1925},"s-3tI"," data",[130,1928,163],{"class":162},[130,1930,724],{"class":597},[130,1932,505],{"class":162},[130,1934,555],{"class":554},[130,1936,603],{"class":136},[130,1938,1939],{"class":143}," useFetch",[130,1941,148],{"class":158},[130,1943,201],{"class":193},[130,1945,1946],{"class":197},"/api/articles",[130,1948,201],{"class":193},[130,1950,325],{"class":162},[130,1952,166],{"class":162},[130,1954,1955,1958,1960,1962,1964,1966,1969,1972,1975],{"class":132,"line":207},[130,1956,1957],{"class":143},"    default",[130,1959,163],{"class":162},[130,1961,1912],{"class":162},[130,1963,163],{"class":554},[130,1965,865],{"class":570},[130,1967,1968],{"class":158},"[] ",[130,1970,1971],{"class":546},"=>",[130,1973,1974],{"class":158}," []",[130,1976,204],{"class":162},[130,1978,1979,1982],{"class":132,"line":224},[130,1980,1981],{"class":162},"  }",[130,1983,338],{"class":158},[130,1985,1986],{"class":132,"line":245},[130,1987,420],{"emptyLinePlaceholder":419},[130,1989,1990,1992,1994,1996],{"class":132,"line":265},[130,1991,678],{"class":136},[130,1993,499],{"class":162},[130,1995,724],{"class":180},[130,1997,1998],{"class":162}," }\n",[130,2000,2001],{"class":132,"line":283},[130,2002,686],{"class":162},[130,2004,2005],{"class":132,"line":302},[130,2006,420],{"emptyLinePlaceholder":419},[130,2008,2009,2011,2013,2016,2018,2020,2022,2024,2026,2028,2030,2032],{"class":132,"line":332},[130,2010,137],{"class":136},[130,2012,547],{"class":546},[130,2014,2015],{"class":550}," useArticle",[130,2017,555],{"class":554},[130,2019,558],{"class":546},[130,2021,561],{"class":162},[130,2023,640],{"class":564},[130,2025,163],{"class":554},[130,2027,581],{"class":580},[130,2029,584],{"class":162},[130,2031,587],{"class":546},[130,2033,166],{"class":162},[130,2035,2036,2038,2040,2042,2044,2046,2048,2050,2052,2054,2056,2059,2062,2064,2066,2068,2070,2073,2075,2077,2079],{"class":132,"line":341},[130,2037,594],{"class":546},[130,2039,499],{"class":162},[130,2041,1926],{"class":1925},[130,2043,163],{"class":162},[130,2045,598],{"class":597},[130,2047,505],{"class":162},[130,2049,555],{"class":554},[130,2051,603],{"class":136},[130,2053,1939],{"class":143},[130,2055,608],{"class":162},[130,2057,2058],{"class":570},"ArticleCollectionItem",[130,2060,2061],{"class":554}," |",[130,2063,1171],{"class":580},[130,2065,618],{"class":162},[130,2067,148],{"class":158},[130,2069,645],{"class":193},[130,2071,2072],{"class":197},"/api/articles/",[130,2074,651],{"class":193},[130,2076,640],{"class":180},[130,2078,657],{"class":193},[130,2080,204],{"class":162},[130,2082,2083],{"class":132,"line":349},[130,2084,2085],{"class":162},"    {\n",[130,2087,2088,2091,2093,2095,2097,2099],{"class":132,"line":355},[130,2089,2090],{"class":143},"      default",[130,2092,163],{"class":162},[130,2094,1912],{"class":162},[130,2096,587],{"class":546},[130,2098,1171],{"class":1170},[130,2100,204],{"class":162},[130,2102,2103],{"class":132,"line":783},[130,2104,2105],{"class":162},"    }\n",[130,2107,2108],{"class":132,"line":793},[130,2109,1533],{"class":158},[130,2111,2112],{"class":132,"line":798},[130,2113,420],{"emptyLinePlaceholder":419},[130,2115,2116,2118,2120,2122],{"class":132,"line":806},[130,2117,678],{"class":136},[130,2119,499],{"class":162},[130,2121,598],{"class":180},[130,2123,1998],{"class":162},[130,2125,2126],{"class":132,"line":1073},[130,2127,686],{"class":162},[11,2129,2131],{"id":2130},"template","Template",[16,2133,2134],{},"Composables を呼ぶだけですが、一応テンプレートです。",[83,2136,2141],{"className":2137,"code":2138,"filename":2139,"language":2140,"meta":92,"style":92},"language-vue shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","\u003Cscritp setup lang=\"ts\">\nconst { articles } = await useArticles()\n\u003C/scritp>\n\n\u003Ctemplate>\n  \u003C!-- 割愛します -->\n\u003C/template>\n","~/app/pages/index.vue","vue",[90,2142,2143,2171,2189,2198,2202,2210,2221],{"__ignoreMap":92},[130,2144,2145,2147,2151,2155,2158,2161,2164,2166,2168],{"class":132,"line":133},[130,2146,608],{"class":162},[130,2148,2150],{"class":2149},"siCa7","scritp",[130,2152,2154],{"class":2153},"sOohs"," setup",[130,2156,2157],{"class":2153}," lang",[130,2159,2160],{"class":162},"=",[130,2162,2163],{"class":193},"\"",[130,2165,126],{"class":197},[130,2167,2163],{"class":193},[130,2169,2170],{"class":162},">\n",[130,2172,2173,2175,2177,2179,2181,2183,2185,2187],{"class":132,"line":155},[130,2174,1012],{"class":546},[130,2176,499],{"class":162},[130,2178,724],{"class":597},[130,2180,505],{"class":162},[130,2182,555],{"class":554},[130,2184,603],{"class":136},[130,2186,1905],{"class":143},[130,2188,669],{"class":180},[130,2190,2191,2194,2196],{"class":132,"line":169},[130,2192,2193],{"class":554},"\u003C/",[130,2195,2150],{"class":180},[130,2197,2170],{"class":554},[130,2199,2200],{"class":132,"line":185},[130,2201,420],{"emptyLinePlaceholder":419},[130,2203,2204,2206,2208],{"class":132,"line":207},[130,2205,608],{"class":180},[130,2207,2130],{"class":570},[130,2209,2170],{"class":180},[130,2211,2212,2215,2218],{"class":132,"line":224},[130,2213,2214],{"class":554},"  \u003C!--",[130,2216,2217],{"class":180}," 割愛します ",[130,2219,2220],{"class":554},"-->\n",[130,2222,2223,2225,2227],{"class":132,"line":245},[130,2224,2193],{"class":554},[130,2226,2130],{"class":180},[130,2228,2170],{"class":554},[83,2230,2233],{"className":2137,"code":2231,"filename":2232,"language":2140,"meta":92,"style":92},"\u003Cscritp setup lang=\"ts\">\nconst route = useRoute()\nconst slug = route.params.slug\nconst { article } = await useArticle(slug)\n\nif (article === null) {\n  throw createError({ statusCode: 404, message: 'Article Not Found.' })\n}\n\u003C/scritp>\n\n\u003Ctemplate>\n  \u003C!-- 割愛します -->\n\u003C/template>\n","~/app/pages/[slug]/index.vue",[90,2234,2235,2255,2269,2289,2308,2312,2329,2369,2373,2381,2385,2393,2401],{"__ignoreMap":92},[130,2236,2237,2239,2241,2243,2245,2247,2249,2251,2253],{"class":132,"line":133},[130,2238,608],{"class":162},[130,2240,2150],{"class":2149},[130,2242,2154],{"class":2153},[130,2244,2157],{"class":2153},[130,2246,2160],{"class":162},[130,2248,2163],{"class":193},[130,2250,126],{"class":197},[130,2252,2163],{"class":193},[130,2254,2170],{"class":162},[130,2256,2257,2259,2262,2264,2267],{"class":132,"line":155},[130,2258,1012],{"class":546},[130,2260,2261],{"class":597}," route",[130,2263,555],{"class":554},[130,2265,2266],{"class":143}," useRoute",[130,2268,669],{"class":180},[130,2270,2271,2273,2275,2277,2279,2281,2284,2286],{"class":132,"line":169},[130,2272,1012],{"class":546},[130,2274,575],{"class":597},[130,2276,555],{"class":554},[130,2278,2261],{"class":180},[130,2280,235],{"class":162},[130,2282,2283],{"class":180},"params",[130,2285,235],{"class":162},[130,2287,2288],{"class":180},"slug\n",[130,2290,2291,2293,2295,2297,2299,2301,2303,2305],{"class":132,"line":185},[130,2292,1012],{"class":546},[130,2294,499],{"class":162},[130,2296,598],{"class":597},[130,2298,505],{"class":162},[130,2300,555],{"class":554},[130,2302,603],{"class":136},[130,2304,2015],{"class":143},[130,2306,2307],{"class":180},"(slug)\n",[130,2309,2310],{"class":132,"line":207},[130,2311,420],{"emptyLinePlaceholder":419},[130,2313,2314,2317,2320,2323,2325,2327],{"class":132,"line":224},[130,2315,2316],{"class":136},"if",[130,2318,2319],{"class":180}," (article ",[130,2321,2322],{"class":554},"===",[130,2324,1171],{"class":1170},[130,2326,1174],{"class":180},[130,2328,152],{"class":162},[130,2330,2331,2334,2337,2339,2342,2345,2347,2351,2353,2356,2358,2360,2363,2365,2367],{"class":132,"line":245},[130,2332,2333],{"class":136},"  throw",[130,2335,2336],{"class":143}," createError",[130,2338,148],{"class":158},[130,2340,2341],{"class":162},"{",[130,2343,2344],{"class":158}," statusCode",[130,2346,163],{"class":162},[130,2348,2350],{"class":2349},"sFHE5"," 404",[130,2352,325],{"class":162},[130,2354,2355],{"class":158}," message",[130,2357,163],{"class":162},[130,2359,194],{"class":193},[130,2361,2362],{"class":197},"Article Not Found.",[130,2364,201],{"class":193},[130,2366,505],{"class":162},[130,2368,338],{"class":158},[130,2370,2371],{"class":132,"line":265},[130,2372,686],{"class":162},[130,2374,2375,2377,2379],{"class":132,"line":283},[130,2376,2193],{"class":554},[130,2378,2150],{"class":180},[130,2380,2170],{"class":554},[130,2382,2383],{"class":132,"line":302},[130,2384,420],{"emptyLinePlaceholder":419},[130,2386,2387,2389,2391],{"class":132,"line":332},[130,2388,608],{"class":180},[130,2390,2130],{"class":570},[130,2392,2170],{"class":180},[130,2394,2395,2397,2399],{"class":132,"line":341},[130,2396,2214],{"class":554},[130,2398,2217],{"class":180},[130,2400,2220],{"class":554},[130,2402,2403,2405,2407],{"class":132,"line":349},[130,2404,2193],{"class":554},[130,2406,2130],{"class":180},[130,2408,2170],{"class":554},[11,2410,2412],{"id":2411},"outro","Outro",[16,2414,2415],{},"以上です。",[16,2417,2418],{},"予約投稿が実装されたので来週からは記事が勝手に投稿されるに違いあるまい。",[2420,2421,2422],"style",{},"html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sipQf, html code.shiki .sipQf{--shiki-light:#90A4AE;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sfFde, html code.shiki .sfFde{--shiki-light:#39ADB5;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sDE9X, html code.shiki .sDE9X{--shiki-light:#90A4AE;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sdaUG, html code.shiki .sdaUG{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .s8Xov, html code.shiki .s8Xov{--shiki-light:#90A4AE;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sywW5, html code.shiki .sywW5{--shiki-light:#E2931D;--shiki-default:#FFB757;--shiki-dark:#B392F0}html pre.shiki code .snYqn, html code.shiki .snYqn{--shiki-light:#E2931D;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sST-Y, html code.shiki .sST-Y{--shiki-light:#9C3EDA;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sm6hg, html code.shiki .sm6hg{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#F0F3F6;--shiki-default-font-style:inherit;--shiki-dark:#E1E4E8;--shiki-dark-font-style:inherit}html pre.shiki code .s4Pz2, html code.shiki .s4Pz2{--shiki-light:#39ADB5;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sBxIE, html code.shiki .sBxIE{--shiki-light:#FF5370;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .s-3tI, html code.shiki .s-3tI{--shiki-light:#E53935;--shiki-default:#FFB757;--shiki-dark:#FFAB70}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sFHE5, html code.shiki .sFHE5{--shiki-light:#F76D47;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}",{"title":92,"searchDepth":169,"depth":169,"links":2424},[2425,2426,2430,2431,2439,2440,2441],{"id":13,"depth":155,"text":14},{"id":55,"depth":155,"text":56,"children":2427},[2428,2429],{"id":78,"depth":169,"text":78},{"id":95,"depth":169,"text":95},{"id":112,"depth":155,"text":113},{"id":471,"depth":155,"text":472,"children":2432},[2433,2434,2435],{"id":478,"depth":169,"text":479},{"id":818,"depth":169,"text":819},{"id":1570,"depth":169,"text":1571,"children":2436},[2437,2438],{"id":1578,"depth":185,"text":1579},{"id":1669,"depth":185,"text":1670},{"id":1865,"depth":155,"text":1866},{"id":2130,"depth":155,"text":2131},{"id":2411,"depth":155,"text":2412},"2026-03-02T00:00:00.000Z","予約投稿、それは希望。未来を信じるもののみに許された「祈り」「願い」「誓い」。僕はそれを実装しようと思う。","/avatar_green_oab8qx.webp",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1772369627/tsukiyama-blog/nuxt-content-scheduled-posts/nuxt-content-scheduled-posts_phjsvn.webp","/tech/nuxt-content-scheduled-posts","2026-03-02T08:00:00.000Z",{"title":6,"description":2443},"tech/nuxt-content-scheduled-posts",[2452,2453,2454],"Nuxt.js","Nuxt Content","Day.js",null,"mBwY_VreOiSGnKHu370nVi_e6n8uUFvqyM8lqu0JcwU",{"id":2458,"title":2459,"body":2460,"date":5139,"description":5140,"extension":381,"icon":5141,"meta":5142,"navigation":419,"ogImage":5143,"path":5144,"published":419,"publishedAt":2455,"seo":5145,"stem":5146,"tags":5147,"updatedAt":2455,"__hash__":5150},"tech/tech/image-optimization.md","Webページの画像最適化について学びなおす",{"type":8,"value":2461,"toc":5108},[2462,2465,2472,2475,2485,2488,2491,2494,2503,2506,2522,2526,2529,2538,2540,2546,2549,2555,2559,2565,2581,2587,2591,2600,2603,2621,2631,2637,2645,2669,2671,2674,2682,2712,2721,2761,2864,2875,2879,2886,2914,2918,2947,2950,2956,2959,3064,3067,3110,3113,3133,3140,3170,3173,3177,3202,3207,3211,3229,3233,3237,3257,3261,3264,3411,3414,3417,3420,3423,3429,3717,3731,3734,3737,3747,3756,3824,3827,3830,3833,3837,3840,3847,3850,3856,3859,3866,3872,3883,3886,4539,4543,4550,4553,4556,4560,4565,4671,4676,4757,4769,4776,4779,4785,4854,4860,5025,5030,5033,5090,5093,5096,5099,5102,5105],[11,2463,2464],{"id":2464},"はじめに",[16,2466,2467,2468,2471],{},"あなたのWebサイトは ",[106,2469,2470],{},"画像最適化"," について意識できていますか？",[16,2473,2474],{},"僕自身、曖昧な知識でできた気になっていたので、フロントエンド側でできる画像最適化を体系的にまとめてみようと本記事を書き始めました。",[2476,2477,2478],"warning",{},[16,2479,2480,2481,2484],{},"本記事は ",[106,2482,2483],{},"フロントエンド視点の最適化","に焦点を当てています。サーバー側の圧縮や CDN 配信戦略などは扱いません。",[11,2486,2487],{"id":2487},"画像最適化しないと起こること",[16,2489,2490],{},"最適化について理解するために、まずは最適化されていない場合に起こり得る問題を挙げて恐怖を植え付けていきたいと思います。",[76,2492,2493],{"id":2493},"ページ表示スピードが遅くなる",[16,2495,2496,2499,2500,2502],{},[106,2497,2498],{},"人生が有限である以上スピードは命","です。",[35,2501],{},"\nユーザーは日々コンテンツの摂取に忙しいです、0.1秒でも表示が遅ければ他のコンテンツを探し始めます。一度離脱したユーザーを呼び戻すのは難しいので機嫌を損ねないようにしなければなりません。",[76,2504,2505],{"id":2505},"検索エンジンも機嫌を損ねる",[16,2507,2508,2509,2515,2516,2518,2519,2521],{},"Google が Core Web vitals という指標を発表し、フロントエンドエンジニア界で一般的になり久しいですが、その指標の一つである ",[106,2510,2511,2514],{},[90,2512,2513],{},"LCP"," (Largest Contentful Paint) の 約70% が画像が原因","となっています。",[35,2517],{},"\nCore Web vitals がSEOに影響を与えることは Google が公言していることから検索エンジンも機嫌を損ねます。",[35,2520],{},"\n検索エンジンが機嫌を損ねると検索順位が下がるのでユーザーがきてくれなくなります。",[2523,2524],"external-link-card-wrapper",{"url":2525},"https://developers.google.com/search/docs/appearance/core-web-vitals?hl=ja",[76,2527,2528],{"id":2528},"コストがかかる",[16,2530,2531,2532,2534,2535,2537],{},"最適化されていない画像はファイルサイズが大きくなりがちです。",[35,2533],{},"\nCDN やホスティング、トラフィックに応じた従量課金制のインフラを利用している場合、転送量に比例してコストが膨らみます。",[35,2536],{},"\nまた、ユーザー側にも無駄なデータ通信を強いることになるので双方にとってメリットがありません。",[371,2539],{},[16,2541,2542,2543,2545],{},"また、現代の Web ページでは中央値でも15〜20枚、リッチなページでは数十枚以上 の画像が使われています。",[35,2544],{},"\n最適化しないことにより、これらの問題が複数枚の画像で発生し、雪だるま式に悪化していきます。",[2523,2547],{"url":2548},"https://almanac.httparchive.org/en/2021/media",[16,2550,2551,2552,2554],{},"ユーザーと検索エンジンに匙を投げられ、お金も尽き、誰にもみられないWebページを前に、ひとり画像の表示を待ちながら今際の際を迎えることになります。",[35,2553],{},"\n恐ろしいですね。",[11,2556,2558],{"id":2557},"画像を何に対して最適化するのか","画像を”何”に対して最適化するのか？",[16,2560,2561,2564],{},[106,2562,2563],{},"ユーザーが使うデバイス","に対してです。",[2566,2567,2568,2572,2575,2578],"ul",{},[2569,2570,2571],"li",{},"画面の大きさ",[2569,2573,2574],{},"解像度",[2569,2576,2577],{},"通信環境",[2569,2579,2580],{},"処理性能",[16,2582,2583,2584,2586],{},"などユーザーの閲覧環境は千差万別です。",[35,2585],{},"\nにもかかわらず、画像リソースをひとつしか用意していないのはユニバーサルでもアクセシブルでもサスティナブルでもないのです。",[11,2588,2590],{"id":2589},"解像度ごとに最適な画像を表示する","“解像度”ごとに最適な画像を表示する",[16,2592,2593,561,2596,2599],{},[90,2594,2595],{},"DPR",[90,2597,2598],{},"Device Pixel Ratio",") という概念があり、詳しくは以下の記事を読んでください。",[2523,2601],{"url":2602},"https://developer.mozilla.org/ja/docs/Web/API/Window/devicePixelRatio",[16,2604,2605,2606,2609,2610,2613,2614,2616,561,2618,2620],{},"ピクセルには",[106,2607,2608],{},"物理ピクセル","と",[106,2611,2612],{},"CSSピクセル","の2つあります。",[35,2615],{},[90,2617,2595],{},[90,2619,2598],{},") はCSSピクセルに対する物理ピクセルの比率です。",[16,2622,2623,2624,2627,2628,2630],{},"かつては",[90,2625,2626],{},"DPR = 1","のデバイスしかありませんでした。",[35,2629],{},"\nなので、物理ピクセルとCSSピクセルは等価でした。",[16,2632,2633,2634,2636],{},"時代は流れディスプレイの画素が上がっていきます。すると、",[90,2635,2626],{},"（1 CSSピクセル = 1 物理ピクセル）の前提では対応しきれなくなりました。\n（CSSピクセルと物理ピクセルが等価だと高解像度画面で小さく見えてしまう）",[16,2638,2639,2640,148,2642,2644],{},"物理ピクセルとCSSピクセルのズレを表す仕組みとして",[90,2641,2595],{},[90,2643,2598],{},")が導入されたのです。",[2566,2646,2647,2658],{},[2569,2648,2649,2650],{},"物理ピクセル\n",[2566,2651,2652,2655],{},[2569,2653,2654],{},"ディスプレイが実際に持っている最小のドット（ディスプレイの画素）",[2569,2656,2657],{},"デバイスごとに差がある",[2569,2659,2660,2661],{},"CSS ピクセル\n",[2566,2662,2663,2666],{},[2569,2664,2665],{},"ブラウザ上の論理単位（物理ピクセルと必ずしも一致しない）",[2569,2667,2668],{},"デバイスごとに何個の物理ピクセルに割り当てるかが変わる",[371,2670],{},[16,2672,2673],{},"CSSピクセルで 100px の幅の画像を表示させる場合、DPR = 2 (Retina相当)のデバイスでは 200 物理ピクセル を使って描画をしています。",[2476,2675,2676],{},[16,2677,2678,2679,2681],{},"100px の画像しか用意していないと、DPR = 2 のデバイスでは 200物理px 表示領域があるのに対して 100px の画像を引き延ばして使うので画像がぼやけてしまいます。",[35,2680],{},"\n逆もまた然りで、100 物理px の領域で 200px の画像ソースだと縮小表示されるため画質は保たれますが、余分に転送量とデコード負荷がかかります。",[2683,2684,2691,2698],"div",{"className":2685},[2686,2687,2688,2689,2690],"text-center","mx-auto","flex","flex-col","items-center",[2692,2693],"img",{"alt":2694,"src":2695,"height":2696,"width":2696,"style":2697},"`64x64` の画像を `128x128` (DPR = 2 ならさら)に引き伸ばされてぼやけている僕","https://res.cloudinary.com/dyoyv8djx/image/upload/v1754885264/tsukiyama-blog/image-optimization/tsukiyama-64x64_jczd1i.png",128,"width: 128px",[16,2699,2704,2707,2708,2711],{"className":2700},[2701,2702,2703],"mt-0","opacity-60","text-sm",[90,2705,2706],{},"64x64"," の画像を ",[90,2709,2710],{},"128x128"," (DPR = 2 ならさら)に引き伸ばされてぼやけている僕",[16,2713,2714,2715,2717,2718,2720],{},"この、",[90,2716,2595],{}," ごとに画像を用意します。",[35,2719],{},"\n（どの画像を描画するかはブラウザが決定してくれます。）",[2722,2723,2724,2737],"table",{},[2725,2726,2727],"thead",{},[2728,2729,2730,2734],"tr",{},[2731,2732,2733],"th",{},"デバイス",[2731,2735,2736],{},"用意する画像",[2738,2739,2740,2751],"tbody",{},[2728,2741,2742,2748],{},[2743,2744,2745,2747],"td",{},[90,2746,2595],{}," が 2 のデバイス",[2743,2749,2750],{},"200 x 200 px",[2728,2752,2753,2758],{},[2743,2754,2755,2757],{},[90,2756,2595],{}," が 3 のデバイス",[2743,2759,2760],{},"300 x 300 px",[83,2762,2766],{"className":2763,"code":2764,"language":2765,"meta":92,"style":92},"language-html shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","\u003Cimg\n  src=\"/img/avatar-100.png\"\n  srcset=\"\n    /img/avatar-100.png 1x, // DPR = 1 で使われる画像ソース\n    /img/avatar-200.png 2x, // DPR = 2 で使われる画像ソース\n    /img/avatar-300.png 3x  // DPR = 3 で使われる画像ソース\n  \"\n  width=\"100\"\n  height=\"100\"\n  alt=\"アバター\"\n>\n","html",[90,2767,2768,2775,2790,2799,2804,2809,2814,2819,2833,2846,2860],{"__ignoreMap":92},[130,2769,2770,2772],{"class":132,"line":133},[130,2771,608],{"class":162},[130,2773,2774],{"class":2149},"img\n",[130,2776,2777,2780,2782,2784,2787],{"class":132,"line":155},[130,2778,2779],{"class":2153},"  src",[130,2781,2160],{"class":162},[130,2783,2163],{"class":193},[130,2785,2786],{"class":197},"/img/avatar-100.png",[130,2788,2789],{"class":193},"\"\n",[130,2791,2792,2795,2797],{"class":132,"line":169},[130,2793,2794],{"class":2153},"  srcset",[130,2796,2160],{"class":162},[130,2798,2789],{"class":193},[130,2800,2801],{"class":132,"line":185},[130,2802,2803],{"class":197},"    /img/avatar-100.png 1x, // DPR = 1 で使われる画像ソース\n",[130,2805,2806],{"class":132,"line":207},[130,2807,2808],{"class":197},"    /img/avatar-200.png 2x, // DPR = 2 で使われる画像ソース\n",[130,2810,2811],{"class":132,"line":224},[130,2812,2813],{"class":197},"    /img/avatar-300.png 3x  // DPR = 3 で使われる画像ソース\n",[130,2815,2816],{"class":132,"line":245},[130,2817,2818],{"class":193},"  \"\n",[130,2820,2821,2824,2826,2828,2831],{"class":132,"line":265},[130,2822,2823],{"class":2153},"  width",[130,2825,2160],{"class":162},[130,2827,2163],{"class":193},[130,2829,2830],{"class":197},"100",[130,2832,2789],{"class":193},[130,2834,2835,2838,2840,2842,2844],{"class":132,"line":283},[130,2836,2837],{"class":2153},"  height",[130,2839,2160],{"class":162},[130,2841,2163],{"class":193},[130,2843,2830],{"class":197},[130,2845,2789],{"class":193},[130,2847,2848,2851,2853,2855,2858],{"class":132,"line":302},[130,2849,2850],{"class":2153},"  alt",[130,2852,2160],{"class":162},[130,2854,2163],{"class":193},[130,2856,2857],{"class":197},"アバター",[130,2859,2789],{"class":193},[130,2861,2862],{"class":132,"line":332},[130,2863,2170],{"class":162},[2683,2865,2867,2872],{"className":2866},[2686,2688,2689,2690],[2692,2868],{"alt":2869,"src":2870,"height":2696,"width":2696,"srcSet":2871,"style":2697},"解像度ごとに最適な画像ソースが設定され、くっきりしている僕","https://res.cloudinary.com/dyoyv8djx/image/upload/v1754893394/tsukiyama-blog/image-optimization/tsukiyama-128x128_dxb19q.png","https://res.cloudinary.com/dyoyv8djx/image/upload/v1754893394/tsukiyama-blog/image-optimization/tsukiyama-128x128_dxb19q.png 1x, https://res.cloudinary.com/dyoyv8djx/image/upload/v1754893395/tsukiyama-blog/image-optimization/tsukiyama-256x256_omoir8.png 2x, https://res.cloudinary.com/dyoyv8djx/image/upload/v1754893398/tsukiyama-blog/image-optimization/tsukiyama-384x384_hgygfe.png 3x",[16,2873,2869],{"className":2874},[2701,2702,2703],[76,2876,2878],{"id":2877},"q-どのdprまで考慮すれば良いの","Q. どのDPRまで考慮すれば良いの？",[16,2880,2881,2882,2885],{},"A. ",[90,2883,2884],{},"DPR = 1 ~ 3"," を用意すれば十分です。",[16,2887,2888,2889,2892,2893,2895,2896,2899,2900,2902,2903,2906,2907,2909,2910,2913],{},"最新の iPhone 16 の ",[90,2890,2891],{},"DPR = 3"," です。",[35,2894],{},"\n現行のモバイル端末で ",[90,2897,2898],{},"DPR = 2"," 以下のものはありませんが、古いモニターではまだ ",[90,2901,2626],{}," のものも残っているので ",[90,2904,2905],{},"1 ~ 3"," の画像を配置するのが良さそう。",[35,2908],{},"\n（Android の一部ハイエンド端末には ",[90,2911,2912],{},"DPR = 4"," のものもあります。）",[11,2915,2917],{"id":2916},"画面幅ごとに最適な画像を表示する","\"画面幅\"ごとに最適な画像を表示する",[16,2919,2920,2921,2924,2925,2928,2929,2931,2932,2935,2936,2938,2939,2942,2943,2946],{},"DPR (",[90,2922,2923],{},"1x/2x/3x",") で画像を出し分ける方法は ",[106,2926,2927],{},"CSS 上の表示幅が固定のとき","には向いています。",[35,2930],{},"\n一方、",[90,2933,2934],{},"width: 100%"," のように表示幅が画面幅に応じて変わる画像には向いていません。",[35,2937],{},"\nこの場合は ",[90,2940,2941],{},"w","記述子 + ",[90,2944,2945],{},"sizes"," を使って最適化します。",[16,2948,2949],{},"この記事に画像を配置した時を例に解説していきます。",[16,2951,2952],{},[2692,2953],{"alt":2954,"src":2955},"OGP","https://res.cloudinary.com/dyoyv8djx/image/upload/v1744039369/tsukiyama-blog/tsukiyama.blog_uaoqwg.png",[16,2957,2958],{},"本ブログの記事レイアウトはざっくり以下のようになっています。",[83,2960,2962],{"className":2763,"code":2961,"language":2765,"meta":92,"style":92},"\u003Cmain class=\"max-w-[1200px] p-4\">\n  \u003Csection class=\"grid gap-8 grid-cols-1 md:grid-cols-[1fr_300px]\">\n    \u003Cmain class=\"w-full max-w-[836px]\">\n      \u003Cimg> // 画像が表示される場所\n    \u003C/main>\n  \u003C/section>\n\u003C/main>\n",[90,2963,2964,2985,3006,3026,3038,3047,3056],{"__ignoreMap":92},[130,2965,2966,2968,2971,2974,2976,2978,2981,2983],{"class":132,"line":133},[130,2967,608],{"class":162},[130,2969,2970],{"class":2149},"main",[130,2972,2973],{"class":2153}," class",[130,2975,2160],{"class":162},[130,2977,2163],{"class":193},[130,2979,2980],{"class":197},"max-w-[1200px] p-4",[130,2982,2163],{"class":193},[130,2984,2170],{"class":162},[130,2986,2987,2990,2993,2995,2997,2999,3002,3004],{"class":132,"line":155},[130,2988,2989],{"class":162},"  \u003C",[130,2991,2992],{"class":2149},"section",[130,2994,2973],{"class":2153},[130,2996,2160],{"class":162},[130,2998,2163],{"class":193},[130,3000,3001],{"class":197},"grid gap-8 grid-cols-1 md:grid-cols-[1fr_300px]",[130,3003,2163],{"class":193},[130,3005,2170],{"class":162},[130,3007,3008,3011,3013,3015,3017,3019,3022,3024],{"class":132,"line":169},[130,3009,3010],{"class":162},"    \u003C",[130,3012,2970],{"class":2149},[130,3014,2973],{"class":2153},[130,3016,2160],{"class":162},[130,3018,2163],{"class":193},[130,3020,3021],{"class":197},"w-full max-w-[836px]",[130,3023,2163],{"class":193},[130,3025,2170],{"class":162},[130,3027,3028,3031,3033,3035],{"class":132,"line":185},[130,3029,3030],{"class":162},"      \u003C",[130,3032,2692],{"class":2149},[130,3034,618],{"class":162},[130,3036,3037],{"class":180}," // 画像が表示される場所\n",[130,3039,3040,3043,3045],{"class":132,"line":207},[130,3041,3042],{"class":162},"    \u003C/",[130,3044,2970],{"class":2149},[130,3046,2170],{"class":162},[130,3048,3049,3052,3054],{"class":132,"line":224},[130,3050,3051],{"class":162},"  \u003C/",[130,3053,2992],{"class":2149},[130,3055,2170],{"class":162},[130,3057,3058,3060,3062],{"class":132,"line":245},[130,3059,2193],{"class":162},[130,3061,2970],{"class":2149},[130,3063,2170],{"class":162},[16,3065,3066],{},"ブレークポイントごとに画像サイズをまとめると",[2566,3068,3069,3081,3098],{},[2569,3070,3071,3074],{},[106,3072,3073],{},"768px 未満",[2566,3075,3076],{},[2569,3077,3078],{},[90,3079,3080],{},"100vw(画面全体) - 2rem(左右の余白)",[2569,3082,3083,3086],{},[106,3084,3085],{},"768px 以上 1200px 未満",[2566,3087,3088],{},[2569,3089,3090,3093,3094,3097],{},[90,3091,3092],{},"100vw(画面全体) - 300px(右カラム分) - 2rem(左右の余白)"," または ",[90,3095,3096],{},"836px(max-width)"," の小さい方",[2569,3099,3100,3103],{},[106,3101,3102],{},"1200px 以上",[2566,3104,3105],{},[2569,3106,3107,3109],{},[90,3108,3096],{}," 固定",[16,3111,3112],{},"この情報を sizes 属性に持たせます。",[83,3114,3116],{"className":2763,"code":3115,"language":2765,"meta":92,"style":92},"sizes=\"(min-width: 1200px) 836px,\n       (min-width: 768px) min(836px, calc(100vw - 300px - 2rem)),\n       calc(100vw - 2rem)\"\n",[90,3117,3118,3123,3128],{"__ignoreMap":92},[130,3119,3120],{"class":132,"line":133},[130,3121,3122],{"class":180},"sizes=\"(min-width: 1200px) 836px,\n",[130,3124,3125],{"class":132,"line":155},[130,3126,3127],{"class":180},"       (min-width: 768px) min(836px, calc(100vw - 300px - 2rem)),\n",[130,3129,3130],{"class":132,"line":169},[130,3131,3132],{"class":180},"       calc(100vw - 2rem)\"\n",[16,3134,3135,3136,3139],{},"また、サイズごとにバリエーションを持たせた画像を ",[90,3137,3138],{},"srcset"," に配置します。",[83,3141,3143],{"className":2763,"code":3142,"language":2765,"meta":92,"style":92},"srcset=\"/img/480w.png 480w,\n        /img/720w.png 720w,\n        /img/960w.png 960w,\n        /img/1280w.png 1280w,\n        /img/1600w.png 1600w\"\n",[90,3144,3145,3150,3155,3160,3165],{"__ignoreMap":92},[130,3146,3147],{"class":132,"line":133},[130,3148,3149],{"class":180},"srcset=\"/img/480w.png 480w,\n",[130,3151,3152],{"class":132,"line":155},[130,3153,3154],{"class":180},"        /img/720w.png 720w,\n",[130,3156,3157],{"class":132,"line":169},[130,3158,3159],{"class":180},"        /img/960w.png 960w,\n",[130,3161,3162],{"class":132,"line":185},[130,3163,3164],{"class":180},"        /img/1280w.png 1280w,\n",[130,3166,3167],{"class":132,"line":207},[130,3168,3169],{"class":180},"        /img/1600w.png 1600w\"\n",[16,3171,3172],{},"これらの情報をもとにブラウザは必要最小限の画像を1つだけダウンロードします。",[76,3174,3176],{"id":3175},"例1-画面幅-390px-dpr-2","例1) 画面幅 390px / DPR = 2",[3178,3179,3180,3190,3196],"ol",{},[2569,3181,3182,3183,3186,3187],{},"sizes = 768px 未満 = ",[90,3184,3185],{},"calc(390px - 2rem(32px))"," = ",[90,3188,3189],{},"358px",[2569,3191,3192,3193],{},"必要ピクセル数 = ",[90,3194,3195],{},"358(CSSピクセル) * 2(DPR) = 716px",[2569,3197,3198,3199],{},"候補から一番近い画像 = ",[90,3200,3201],{},"/img/720w.png",[16,3203,3204,3206],{},[90,3205,3201],{}," の画像が選択されます。",[76,3208,3210],{"id":3209},"例2-画面幅-1200px-dpr-2","例2) 画面幅 1200px / DPR = 2",[3178,3212,3213,3219,3224],{},[2569,3214,3215,3216],{},"sizes = 1200px 以上 = ",[90,3217,3218],{},"836px",[2569,3220,3192,3221],{},[90,3222,3223],{},"836(CSSピクセル) * 2(DPR) = 1672px",[2569,3225,3198,3226],{},[90,3227,3228],{},"/img/1600w.png",[16,3230,3231,3206],{},[90,3232,3228],{},[76,3234,3236],{"id":3235},"例3-画面幅-1024px-dpr-1","例3) 画面幅 1024px / DPR = 1",[3178,3238,3239,3248,3253],{},[2569,3240,3241,3242,3186,3245],{},"sizes = 768px 以上 1200px 未満 = ",[90,3243,3244],{},"min(836px, calc(1024px - 300px - 2rem(32px)))",[90,3246,3247],{},"692px",[2569,3249,3192,3250],{},[90,3251,3252],{},"692(CSSピクセル) × 1(DPR) = 692px",[2569,3254,3198,3255],{},[90,3256,3201],{},[16,3258,3259,3206],{},[90,3260,3201],{},[76,3262,3263],{"id":3263},"コードとプレビュー",[3265,3266,3267,3389],"tabs",{},[3268,3269,3272],"tabs-item",{"icon":3270,"label":3271},"i-lucide-code","Code",[83,3273,3275],{"className":2763,"code":3274,"language":2765,"meta":92,"style":92},"\u003Cimg\n  src=\"/img/960w.png\"\n  srcset=\"/img/480w.png 480w,\n        /img/720w.png 720w,\n        /img/960w.png 960w,\n        /img/1280w.png 1280w,\n        /img/1600w.png 1600w\"\n  sizes=\"(min-width: 1200px) 836px,\n         (min-width: 768px) min(836px, calc(100vw - 300px - 2rem)),\n         calc(100vw - 2rem)\"\n  width=\"720\"\n  height=\"405\"\n  alt=\"\"\n>\n",[90,3276,3277,3283,3296,3307,3311,3315,3319,3326,3338,3343,3350,3363,3376,3385],{"__ignoreMap":92},[130,3278,3279,3281],{"class":132,"line":133},[130,3280,608],{"class":162},[130,3282,2774],{"class":2149},[130,3284,3285,3287,3289,3291,3294],{"class":132,"line":155},[130,3286,2779],{"class":2153},[130,3288,2160],{"class":162},[130,3290,2163],{"class":193},[130,3292,3293],{"class":197},"/img/960w.png",[130,3295,2789],{"class":193},[130,3297,3298,3300,3302,3304],{"class":132,"line":169},[130,3299,2794],{"class":2153},[130,3301,2160],{"class":162},[130,3303,2163],{"class":193},[130,3305,3306],{"class":197},"/img/480w.png 480w,\n",[130,3308,3309],{"class":132,"line":185},[130,3310,3154],{"class":197},[130,3312,3313],{"class":132,"line":207},[130,3314,3159],{"class":197},[130,3316,3317],{"class":132,"line":224},[130,3318,3164],{"class":197},[130,3320,3321,3324],{"class":132,"line":245},[130,3322,3323],{"class":197},"        /img/1600w.png 1600w",[130,3325,2789],{"class":193},[130,3327,3328,3331,3333,3335],{"class":132,"line":265},[130,3329,3330],{"class":2153},"  sizes",[130,3332,2160],{"class":162},[130,3334,2163],{"class":193},[130,3336,3337],{"class":197},"(min-width: 1200px) 836px,\n",[130,3339,3340],{"class":132,"line":283},[130,3341,3342],{"class":197},"         (min-width: 768px) min(836px, calc(100vw - 300px - 2rem)),\n",[130,3344,3345,3348],{"class":132,"line":302},[130,3346,3347],{"class":197},"         calc(100vw - 2rem)",[130,3349,2789],{"class":193},[130,3351,3352,3354,3356,3358,3361],{"class":132,"line":332},[130,3353,2823],{"class":2153},[130,3355,2160],{"class":162},[130,3357,2163],{"class":193},[130,3359,3360],{"class":197},"720",[130,3362,2789],{"class":193},[130,3364,3365,3367,3369,3371,3374],{"class":132,"line":341},[130,3366,2837],{"class":2153},[130,3368,2160],{"class":162},[130,3370,2163],{"class":193},[130,3372,3373],{"class":197},"405",[130,3375,2789],{"class":193},[130,3377,3378,3380,3382],{"class":132,"line":349},[130,3379,2850],{"class":2153},[130,3381,2160],{"class":162},[130,3383,3384],{"class":193},"\"\"\n",[130,3386,3387],{"class":132,"line":355},[130,3388,2170],{"class":162},[3268,3390,3393,3403],{"icon":3391,"label":3392},"i-lucide-eye","Preview",[16,3394,3395,3398,3399,3402],{},[90,3396,3397],{},"DevTools"," の ",[90,3400,3401],{},"Responsice"," で 画面幅を変えて確認してください",[2692,3404],{"alt":3405,"src":3406,"height":3407,"width":3408,"srcSet":3409,"sizes":3410},"参考画像","https://res.cloudinary.com/dyoyv8djx/image/upload/v1754897806/tsukiyama-blog/image-optimization/w960_blksmf.png",405,720,"https://res.cloudinary.com/dyoyv8djx/image/upload/v1754897805/tsukiyama-blog/image-optimization/w480_t88n2r.png 480w,\n          https://res.cloudinary.com/dyoyv8djx/image/upload/v1754897807/tsukiyama-blog/image-optimization/w720_vlgvo5.png 720w,\n          https://res.cloudinary.com/dyoyv8djx/image/upload/v1754897806/tsukiyama-blog/image-optimization/w960_blksmf.png 960w,\n          https://res.cloudinary.com/dyoyv8djx/image/upload/v1754897805/tsukiyama-blog/image-optimization/w1280_saydvq.png 1280w,\n          https://res.cloudinary.com/dyoyv8djx/image/upload/v1754897805/tsukiyama-blog/image-optimization/w1600_ar2ubh.png 1600w","(min-width: 1200px) 836px,\n         (min-width: 768px) min(836px, calc(100vw - 300px - 2rem)),\n         calc(100vw - 2rem)",[11,3412,3413],{"id":3413},"次世代フォーマットの活用",[16,3415,3416],{},"詳しい説明は以下記事に譲ります。",[2523,3418],{"url":3419},"https://zenn.dev/xx_suzuki/articles/sharp-verification",[2523,3421],{"url":3422},"https://ics.media/entry/201001/",[16,3424,3425,3426,3428],{},"これらのフォーマットは一般的になりつつありますが、まだ対応していないブラウザも見受けられます。",[35,3427],{},"\n未対応ブラウザ用にフォールバック画像を設定するのが親切です。",[83,3430,3432],{"className":2763,"code":3431,"language":2765,"meta":92,"style":92},"\u003Cpicture>\n  \u003C!-- AVIF -->\n  \u003Csource\n    type=\"image/avif\"\n    srcset=\"/img/hero-480.avif 480w,\n            /img/hero-720.avif 720w,\n            /img/hero-960.avif 960w,\n            /img/hero-1280.avif 1280w,\n            /img/hero-1600.avif 1600w\"\n    sizes=\"(min-width: 768px) 720px, calc(100vw - 2rem)\"\n  >\n  \u003C!-- WebP -->\n  \u003Csource\n    type=\"image/webp\"\n    srcset=\"/img/hero-480.webp 480w,\n            /img/hero-720.webp 720w,\n            /img/hero-960.webp 960w,\n            /img/hero-1280.webp 1280w,\n            /img/hero-1600.webp 1600w\"\n    sizes=\"(min-width: 768px) 720px, calc(100vw - 2rem)\"\n  >\n  \u003C!-- フォールバック（PNG） -->\n  \u003Cimg\n    src=\"/img/hero-960.png\"\n    srcset=\"/img/hero-480.png 480w,\n            /img/hero-720.png 720w,\n            /img/hero-960.png 960w,\n            /img/hero-1280.png 1280w,\n            /img/hero-1600.png 1600w\"\n    sizes=\"(min-width: 768px) 720px, calc(100vw - 2rem)\"\n    width=\"720\"\n    height=\"405\"\n    alt=\"ヒーロー画像\"\n  >\n\u003C/picture>\n\n",[90,3433,3434,3443,3448,3455,3469,3481,3486,3491,3496,3503,3517,3522,3527,3533,3546,3557,3562,3567,3572,3579,3591,3595,3600,3606,3620,3631,3636,3641,3646,3653,3665,3678,3691,3705,3709],{"__ignoreMap":92},[130,3435,3436,3438,3441],{"class":132,"line":133},[130,3437,608],{"class":162},[130,3439,3440],{"class":2149},"picture",[130,3442,2170],{"class":162},[130,3444,3445],{"class":132,"line":155},[130,3446,3447],{"class":328},"  \u003C!-- AVIF -->\n",[130,3449,3450,3452],{"class":132,"line":169},[130,3451,2989],{"class":162},[130,3453,3454],{"class":2149},"source\n",[130,3456,3457,3460,3462,3464,3467],{"class":132,"line":185},[130,3458,3459],{"class":2153},"    type",[130,3461,2160],{"class":162},[130,3463,2163],{"class":193},[130,3465,3466],{"class":197},"image/avif",[130,3468,2789],{"class":193},[130,3470,3471,3474,3476,3478],{"class":132,"line":207},[130,3472,3473],{"class":2153},"    srcset",[130,3475,2160],{"class":162},[130,3477,2163],{"class":193},[130,3479,3480],{"class":197},"/img/hero-480.avif 480w,\n",[130,3482,3483],{"class":132,"line":224},[130,3484,3485],{"class":197},"            /img/hero-720.avif 720w,\n",[130,3487,3488],{"class":132,"line":245},[130,3489,3490],{"class":197},"            /img/hero-960.avif 960w,\n",[130,3492,3493],{"class":132,"line":265},[130,3494,3495],{"class":197},"            /img/hero-1280.avif 1280w,\n",[130,3497,3498,3501],{"class":132,"line":283},[130,3499,3500],{"class":197},"            /img/hero-1600.avif 1600w",[130,3502,2789],{"class":193},[130,3504,3505,3508,3510,3512,3515],{"class":132,"line":302},[130,3506,3507],{"class":2153},"    sizes",[130,3509,2160],{"class":162},[130,3511,2163],{"class":193},[130,3513,3514],{"class":197},"(min-width: 768px) 720px, calc(100vw - 2rem)",[130,3516,2789],{"class":193},[130,3518,3519],{"class":132,"line":332},[130,3520,3521],{"class":162},"  >\n",[130,3523,3524],{"class":132,"line":341},[130,3525,3526],{"class":328},"  \u003C!-- WebP -->\n",[130,3528,3529,3531],{"class":132,"line":349},[130,3530,2989],{"class":162},[130,3532,3454],{"class":2149},[130,3534,3535,3537,3539,3541,3544],{"class":132,"line":355},[130,3536,3459],{"class":2153},[130,3538,2160],{"class":162},[130,3540,2163],{"class":193},[130,3542,3543],{"class":197},"image/webp",[130,3545,2789],{"class":193},[130,3547,3548,3550,3552,3554],{"class":132,"line":783},[130,3549,3473],{"class":2153},[130,3551,2160],{"class":162},[130,3553,2163],{"class":193},[130,3555,3556],{"class":197},"/img/hero-480.webp 480w,\n",[130,3558,3559],{"class":132,"line":793},[130,3560,3561],{"class":197},"            /img/hero-720.webp 720w,\n",[130,3563,3564],{"class":132,"line":798},[130,3565,3566],{"class":197},"            /img/hero-960.webp 960w,\n",[130,3568,3569],{"class":132,"line":806},[130,3570,3571],{"class":197},"            /img/hero-1280.webp 1280w,\n",[130,3573,3574,3577],{"class":132,"line":1073},[130,3575,3576],{"class":197},"            /img/hero-1600.webp 1600w",[130,3578,2789],{"class":193},[130,3580,3581,3583,3585,3587,3589],{"class":132,"line":1086},[130,3582,3507],{"class":2153},[130,3584,2160],{"class":162},[130,3586,2163],{"class":193},[130,3588,3514],{"class":197},[130,3590,2789],{"class":193},[130,3592,3593],{"class":132,"line":1092},[130,3594,3521],{"class":162},[130,3596,3597],{"class":132,"line":1128},[130,3598,3599],{"class":328},"  \u003C!-- フォールバック（PNG） -->\n",[130,3601,3602,3604],{"class":132,"line":1151},[130,3603,2989],{"class":162},[130,3605,2774],{"class":2149},[130,3607,3608,3611,3613,3615,3618],{"class":132,"line":1156},[130,3609,3610],{"class":2153},"    src",[130,3612,2160],{"class":162},[130,3614,2163],{"class":193},[130,3616,3617],{"class":197},"/img/hero-960.png",[130,3619,2789],{"class":193},[130,3621,3622,3624,3626,3628],{"class":132,"line":1179},[130,3623,3473],{"class":2153},[130,3625,2160],{"class":162},[130,3627,2163],{"class":193},[130,3629,3630],{"class":197},"/img/hero-480.png 480w,\n",[130,3632,3633],{"class":132,"line":1188},[130,3634,3635],{"class":197},"            /img/hero-720.png 720w,\n",[130,3637,3638],{"class":132,"line":1193},[130,3639,3640],{"class":197},"            /img/hero-960.png 960w,\n",[130,3642,3643],{"class":132,"line":1198},[130,3644,3645],{"class":197},"            /img/hero-1280.png 1280w,\n",[130,3647,3648,3651],{"class":132,"line":1222},[130,3649,3650],{"class":197},"            /img/hero-1600.png 1600w",[130,3652,2789],{"class":193},[130,3654,3655,3657,3659,3661,3663],{"class":132,"line":1227},[130,3656,3507],{"class":2153},[130,3658,2160],{"class":162},[130,3660,2163],{"class":193},[130,3662,3514],{"class":197},[130,3664,2789],{"class":193},[130,3666,3667,3670,3672,3674,3676],{"class":132,"line":1232},[130,3668,3669],{"class":2153},"    width",[130,3671,2160],{"class":162},[130,3673,2163],{"class":193},[130,3675,3360],{"class":197},[130,3677,2789],{"class":193},[130,3679,3680,3683,3685,3687,3689],{"class":132,"line":1237},[130,3681,3682],{"class":2153},"    height",[130,3684,2160],{"class":162},[130,3686,2163],{"class":193},[130,3688,3373],{"class":197},[130,3690,2789],{"class":193},[130,3692,3693,3696,3698,3700,3703],{"class":132,"line":1243},[130,3694,3695],{"class":2153},"    alt",[130,3697,2160],{"class":162},[130,3699,2163],{"class":193},[130,3701,3702],{"class":197},"ヒーロー画像",[130,3704,2789],{"class":193},[130,3706,3707],{"class":132,"line":1256},[130,3708,3521],{"class":162},[130,3710,3711,3713,3715],{"class":132,"line":1268},[130,3712,2193],{"class":162},[130,3714,3440],{"class":2149},[130,3716,2170],{"class":162},[16,3718,3719,3720,3723,3724,3727,3728,3730],{},"ブラウザは ",[90,3721,3722],{},"source"," に指定された ",[90,3725,3726],{},"type"," を確認し、対応しているフォーマットであればそのソースに HTTP リクエストを送ります。",[35,3729],{},"\n対応していない場合はリクエストを送らないため、不要な通信を防げます。",[2523,3732],{"url":3733},"https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/picture",[11,3735,3736],{"id":3736},"読み込みタイミングの最適化",[76,3738,3740,3743,3744],{"id":3739},"loadinglazy-decodingasync",[90,3741,3742],{},"loading=\"lazy\""," ＆ ",[90,3745,3746],{},"decoding=\"async\"",[16,3748,3749,3750,3752,3755],{},"初期描画する必要のない（ビューポート外の）画像は初期転送量を減らすために",[35,3751],{},[90,3753,3754],{},"loading=\"lazy\" decoding=\"async\"","が有効です。",[83,3757,3759],{"className":2763,"code":3758,"language":2765,"meta":92,"style":92},"\u003Cimg\n  src=\"/img/hoge.png\"\n  alt=\"初期描画されない画像\"\n  loading=\"lazy\"\n  decoding=\"async\"\n>\n",[90,3760,3761,3767,3780,3793,3807,3820],{"__ignoreMap":92},[130,3762,3763,3765],{"class":132,"line":133},[130,3764,608],{"class":162},[130,3766,2774],{"class":2149},[130,3768,3769,3771,3773,3775,3778],{"class":132,"line":155},[130,3770,2779],{"class":2153},[130,3772,2160],{"class":162},[130,3774,2163],{"class":193},[130,3776,3777],{"class":197},"/img/hoge.png",[130,3779,2789],{"class":193},[130,3781,3782,3784,3786,3788,3791],{"class":132,"line":169},[130,3783,2850],{"class":2153},[130,3785,2160],{"class":162},[130,3787,2163],{"class":193},[130,3789,3790],{"class":197},"初期描画されない画像",[130,3792,2789],{"class":193},[130,3794,3795,3798,3800,3802,3805],{"class":132,"line":185},[130,3796,3797],{"class":2153},"  loading",[130,3799,2160],{"class":162},[130,3801,2163],{"class":193},[130,3803,3804],{"class":197},"lazy",[130,3806,2789],{"class":193},[130,3808,3809,3812,3814,3816,3818],{"class":132,"line":207},[130,3810,3811],{"class":2153},"  decoding",[130,3813,2160],{"class":162},[130,3815,2163],{"class":193},[130,3817,1622],{"class":197},[130,3819,2789],{"class":193},[130,3821,3822],{"class":132,"line":224},[130,3823,2170],{"class":162},[16,3825,3826],{},"これにより、デコードと描画タイミングをスクロール直前まで後ろ倒しにできます。",[2523,3828],{"url":3829},"https://developer.mozilla.org/ja/docs/Web/Performance/Guides/Lazy_loading",[2523,3831],{"url":3832},"https://developer.mozilla.org/ja/docs/Web/API/HTMLImageElement/decoding",[76,3834,3836],{"id":3835},"lcp画像を優先的に先読み","LCP画像を優先的に先読み",[16,3838,3839],{},"初期表示で一番大きく表示する画像(LCP候補)は、ネットワーク優先度を上げると描画が速くなります。",[2566,3841,3842],{},[2569,3843,3844],{},[90,3845,3846],{},"fetchpriority=\"high\"",[16,3848,3849],{},"ブラウザに画像取得をどのように優先させるべきかヒントを表します。",[16,3851,3852,3855],{},[90,3853,3854],{},"high"," を渡すと他の画像と比較して高い優先度で画像を取得します。",[2523,3857],{"url":3858},"https://developer.mozilla.org/ja/docs/Web/API/HTMLImageElement/fetchPriority",[2566,3860,3861],{},[2569,3862,3863],{},[90,3864,3865],{},"preload",[16,3867,3868,3869,3871],{},"ブラウザのレンダリング前に読み込みを始めることができます。",[35,3870],{},"\nこれにより、そのリソースが早く利用でき、レンダリングブロックされるのを防げます。",[16,3873,3874,3875,3878,3879,3882],{},"（",[90,3876,3877],{},"rel=\"preload\"","も",[90,3880,3881],{},"\u003Csource>","同様にMIMEタイプを含めることができます。）",[2523,3884],{"url":3885},"https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Attributes/rel/preload",[83,3887,3889],{"className":2763,"code":3888,"language":2765,"meta":92,"style":92},"\u003Chead>\n  \u003C!-- AVIF -->\n  \u003Clink\n    rel=\"preload\"\n    as=\"image\"\n    href=\"/img/hero-1920w.avif\"\n    imagesrcset=\"/img/hero-720w.avif 720w,\n                 /img/hero-1280w.avif 1280w,\n                 /img/hero-1920w.avif 1920w\"\n    imagesizes=\"100vw\"\n    type=\"image/avif\"\n    fetchpriority=\"high\"\n  />\n  \u003C!-- WebP -->\n  \u003Clink\n    rel=\"preload\"\n    as=\"image\"\n    href=\"/img/hero-1920w.webp\"\n    imagesrcset=\"/img/hero-720w.webp 720w,\n                 /img/hero-1280w.webp 1280w,\n                 /img/hero-1920w.webp 1920w\"\n    imagesizes=\"100vw\"\n    type=\"image/webp\"\n    fetchpriority=\"high\"\n  />\n  \u003C!-- PNG（フォールバック） -->\n  \u003Clink\n    rel=\"preload\"\n    as=\"image\"\n    href=\"/img/hero-1920w.png\"\n    imagesrcset=\"/img/hero-720w.png 720w,\n                 /img/hero-1280w.png 1280w,\n                 /img/hero-1920w.png 1920w\"\n    imagesizes=\"100vw\"\n    type=\"image/png\"\n    fetchpriority=\"high\"\n  />\n\u003C/head>\n\n\u003Cbody>\n  \u003Cpicture>\n    \u003C!-- AVIF -->\n    \u003Csource\n      type=\"image/avif\"\n      srcset=\"/img/hero-720w.avif 720w,\n              /img/hero-1280w.avif 1280w,\n              /img/hero-1920w.avif 1920w\"\n      sizes=\"100vw\"\n    />\n    \u003C!-- WebP -->\n    \u003Csource\n      type=\"image/webp\"\n      srcset=\"/img/hero-720w.webp 720w,\n              /img/hero-1280w.webp 1280w,\n              /img/hero-1920w.webp 1920w\"\n      sizes=\"100vw\"\n    />\n    \u003C!-- PNG（フォールバック） -->\n    \u003Cimg\n      src=\"/img/hero-1920w.png\"\n      srcset=\"/img/hero-720w.png 720w,\n              /img/hero-1280w.png 1280w,\n              /img/hero-1920w.png 1920w\"\n      sizes=\"100vw\"\n      width=\"1920\"\n      height=\"1080\"\n      alt=\"メインビジュアル\"\n      fetchpriority=\"high\"\n    />\n  \u003C/picture>\n\u003C/body>\n\n",[90,3890,3891,3900,3904,3911,3924,3938,3952,3964,3969,3976,3990,4002,4015,4020,4024,4030,4042,4054,4067,4078,4083,4090,4102,4114,4126,4130,4135,4141,4153,4165,4178,4189,4194,4201,4213,4226,4238,4242,4250,4254,4263,4271,4276,4282,4294,4305,4310,4317,4330,4335,4340,4346,4358,4368,4373,4380,4392,4396,4401,4407,4420,4430,4436,4444,4457,4472,4487,4502,4516,4521,4530],{"__ignoreMap":92},[130,3892,3893,3895,3898],{"class":132,"line":133},[130,3894,608],{"class":162},[130,3896,3897],{"class":2149},"head",[130,3899,2170],{"class":162},[130,3901,3902],{"class":132,"line":155},[130,3903,3447],{"class":328},[130,3905,3906,3908],{"class":132,"line":169},[130,3907,2989],{"class":162},[130,3909,3910],{"class":2149},"link\n",[130,3912,3913,3916,3918,3920,3922],{"class":132,"line":185},[130,3914,3915],{"class":2153},"    rel",[130,3917,2160],{"class":162},[130,3919,2163],{"class":193},[130,3921,3865],{"class":197},[130,3923,2789],{"class":193},[130,3925,3926,3929,3931,3933,3936],{"class":132,"line":207},[130,3927,3928],{"class":2153},"    as",[130,3930,2160],{"class":162},[130,3932,2163],{"class":193},[130,3934,3935],{"class":197},"image",[130,3937,2789],{"class":193},[130,3939,3940,3943,3945,3947,3950],{"class":132,"line":224},[130,3941,3942],{"class":2153},"    href",[130,3944,2160],{"class":162},[130,3946,2163],{"class":193},[130,3948,3949],{"class":197},"/img/hero-1920w.avif",[130,3951,2789],{"class":193},[130,3953,3954,3957,3959,3961],{"class":132,"line":245},[130,3955,3956],{"class":2153},"    imagesrcset",[130,3958,2160],{"class":162},[130,3960,2163],{"class":193},[130,3962,3963],{"class":197},"/img/hero-720w.avif 720w,\n",[130,3965,3966],{"class":132,"line":265},[130,3967,3968],{"class":197},"                 /img/hero-1280w.avif 1280w,\n",[130,3970,3971,3974],{"class":132,"line":283},[130,3972,3973],{"class":197},"                 /img/hero-1920w.avif 1920w",[130,3975,2789],{"class":193},[130,3977,3978,3981,3983,3985,3988],{"class":132,"line":302},[130,3979,3980],{"class":2153},"    imagesizes",[130,3982,2160],{"class":162},[130,3984,2163],{"class":193},[130,3986,3987],{"class":197},"100vw",[130,3989,2789],{"class":193},[130,3991,3992,3994,3996,3998,4000],{"class":132,"line":332},[130,3993,3459],{"class":2153},[130,3995,2160],{"class":162},[130,3997,2163],{"class":193},[130,3999,3466],{"class":197},[130,4001,2789],{"class":193},[130,4003,4004,4007,4009,4011,4013],{"class":132,"line":341},[130,4005,4006],{"class":2153},"    fetchpriority",[130,4008,2160],{"class":162},[130,4010,2163],{"class":193},[130,4012,3854],{"class":197},[130,4014,2789],{"class":193},[130,4016,4017],{"class":132,"line":349},[130,4018,4019],{"class":162},"  />\n",[130,4021,4022],{"class":132,"line":355},[130,4023,3526],{"class":328},[130,4025,4026,4028],{"class":132,"line":783},[130,4027,2989],{"class":162},[130,4029,3910],{"class":2149},[130,4031,4032,4034,4036,4038,4040],{"class":132,"line":793},[130,4033,3915],{"class":2153},[130,4035,2160],{"class":162},[130,4037,2163],{"class":193},[130,4039,3865],{"class":197},[130,4041,2789],{"class":193},[130,4043,4044,4046,4048,4050,4052],{"class":132,"line":798},[130,4045,3928],{"class":2153},[130,4047,2160],{"class":162},[130,4049,2163],{"class":193},[130,4051,3935],{"class":197},[130,4053,2789],{"class":193},[130,4055,4056,4058,4060,4062,4065],{"class":132,"line":806},[130,4057,3942],{"class":2153},[130,4059,2160],{"class":162},[130,4061,2163],{"class":193},[130,4063,4064],{"class":197},"/img/hero-1920w.webp",[130,4066,2789],{"class":193},[130,4068,4069,4071,4073,4075],{"class":132,"line":1073},[130,4070,3956],{"class":2153},[130,4072,2160],{"class":162},[130,4074,2163],{"class":193},[130,4076,4077],{"class":197},"/img/hero-720w.webp 720w,\n",[130,4079,4080],{"class":132,"line":1086},[130,4081,4082],{"class":197},"                 /img/hero-1280w.webp 1280w,\n",[130,4084,4085,4088],{"class":132,"line":1092},[130,4086,4087],{"class":197},"                 /img/hero-1920w.webp 1920w",[130,4089,2789],{"class":193},[130,4091,4092,4094,4096,4098,4100],{"class":132,"line":1128},[130,4093,3980],{"class":2153},[130,4095,2160],{"class":162},[130,4097,2163],{"class":193},[130,4099,3987],{"class":197},[130,4101,2789],{"class":193},[130,4103,4104,4106,4108,4110,4112],{"class":132,"line":1151},[130,4105,3459],{"class":2153},[130,4107,2160],{"class":162},[130,4109,2163],{"class":193},[130,4111,3543],{"class":197},[130,4113,2789],{"class":193},[130,4115,4116,4118,4120,4122,4124],{"class":132,"line":1156},[130,4117,4006],{"class":2153},[130,4119,2160],{"class":162},[130,4121,2163],{"class":193},[130,4123,3854],{"class":197},[130,4125,2789],{"class":193},[130,4127,4128],{"class":132,"line":1179},[130,4129,4019],{"class":162},[130,4131,4132],{"class":132,"line":1188},[130,4133,4134],{"class":328},"  \u003C!-- PNG（フォールバック） -->\n",[130,4136,4137,4139],{"class":132,"line":1193},[130,4138,2989],{"class":162},[130,4140,3910],{"class":2149},[130,4142,4143,4145,4147,4149,4151],{"class":132,"line":1198},[130,4144,3915],{"class":2153},[130,4146,2160],{"class":162},[130,4148,2163],{"class":193},[130,4150,3865],{"class":197},[130,4152,2789],{"class":193},[130,4154,4155,4157,4159,4161,4163],{"class":132,"line":1222},[130,4156,3928],{"class":2153},[130,4158,2160],{"class":162},[130,4160,2163],{"class":193},[130,4162,3935],{"class":197},[130,4164,2789],{"class":193},[130,4166,4167,4169,4171,4173,4176],{"class":132,"line":1227},[130,4168,3942],{"class":2153},[130,4170,2160],{"class":162},[130,4172,2163],{"class":193},[130,4174,4175],{"class":197},"/img/hero-1920w.png",[130,4177,2789],{"class":193},[130,4179,4180,4182,4184,4186],{"class":132,"line":1232},[130,4181,3956],{"class":2153},[130,4183,2160],{"class":162},[130,4185,2163],{"class":193},[130,4187,4188],{"class":197},"/img/hero-720w.png 720w,\n",[130,4190,4191],{"class":132,"line":1237},[130,4192,4193],{"class":197},"                 /img/hero-1280w.png 1280w,\n",[130,4195,4196,4199],{"class":132,"line":1243},[130,4197,4198],{"class":197},"                 /img/hero-1920w.png 1920w",[130,4200,2789],{"class":193},[130,4202,4203,4205,4207,4209,4211],{"class":132,"line":1256},[130,4204,3980],{"class":2153},[130,4206,2160],{"class":162},[130,4208,2163],{"class":193},[130,4210,3987],{"class":197},[130,4212,2789],{"class":193},[130,4214,4215,4217,4219,4221,4224],{"class":132,"line":1268},[130,4216,3459],{"class":2153},[130,4218,2160],{"class":162},[130,4220,2163],{"class":193},[130,4222,4223],{"class":197},"image/png",[130,4225,2789],{"class":193},[130,4227,4228,4230,4232,4234,4236],{"class":132,"line":1273},[130,4229,4006],{"class":2153},[130,4231,2160],{"class":162},[130,4233,2163],{"class":193},[130,4235,3854],{"class":197},[130,4237,2789],{"class":193},[130,4239,4240],{"class":132,"line":1301},[130,4241,4019],{"class":162},[130,4243,4244,4246,4248],{"class":132,"line":1320},[130,4245,2193],{"class":162},[130,4247,3897],{"class":2149},[130,4249,2170],{"class":162},[130,4251,4252],{"class":132,"line":1325},[130,4253,420],{"emptyLinePlaceholder":419},[130,4255,4256,4258,4261],{"class":132,"line":1344},[130,4257,608],{"class":162},[130,4259,4260],{"class":2149},"body",[130,4262,2170],{"class":162},[130,4264,4265,4267,4269],{"class":132,"line":1349},[130,4266,2989],{"class":162},[130,4268,3440],{"class":2149},[130,4270,2170],{"class":162},[130,4272,4273],{"class":132,"line":1354},[130,4274,4275],{"class":328},"    \u003C!-- AVIF -->\n",[130,4277,4278,4280],{"class":132,"line":1359},[130,4279,3010],{"class":162},[130,4281,3454],{"class":2149},[130,4283,4284,4286,4288,4290,4292],{"class":132,"line":1365},[130,4285,188],{"class":2153},[130,4287,2160],{"class":162},[130,4289,2163],{"class":193},[130,4291,3466],{"class":197},[130,4293,2789],{"class":193},[130,4295,4296,4299,4301,4303],{"class":132,"line":1379},[130,4297,4298],{"class":2153},"      srcset",[130,4300,2160],{"class":162},[130,4302,2163],{"class":193},[130,4304,3963],{"class":197},[130,4306,4307],{"class":132,"line":1391},[130,4308,4309],{"class":197},"              /img/hero-1280w.avif 1280w,\n",[130,4311,4312,4315],{"class":132,"line":1396},[130,4313,4314],{"class":197},"              /img/hero-1920w.avif 1920w",[130,4316,2789],{"class":193},[130,4318,4319,4322,4324,4326,4328],{"class":132,"line":1419},[130,4320,4321],{"class":2153},"      sizes",[130,4323,2160],{"class":162},[130,4325,2163],{"class":193},[130,4327,3987],{"class":197},[130,4329,2789],{"class":193},[130,4331,4332],{"class":132,"line":1425},[130,4333,4334],{"class":162},"    />\n",[130,4336,4337],{"class":132,"line":1445},[130,4338,4339],{"class":328},"    \u003C!-- WebP -->\n",[130,4341,4342,4344],{"class":132,"line":1454},[130,4343,3010],{"class":162},[130,4345,3454],{"class":2149},[130,4347,4348,4350,4352,4354,4356],{"class":132,"line":1459},[130,4349,188],{"class":2153},[130,4351,2160],{"class":162},[130,4353,2163],{"class":193},[130,4355,3543],{"class":197},[130,4357,2789],{"class":193},[130,4359,4360,4362,4364,4366],{"class":132,"line":1464},[130,4361,4298],{"class":2153},[130,4363,2160],{"class":162},[130,4365,2163],{"class":193},[130,4367,4077],{"class":197},[130,4369,4370],{"class":132,"line":1491},[130,4371,4372],{"class":197},"              /img/hero-1280w.webp 1280w,\n",[130,4374,4375,4378],{"class":132,"line":1510},[130,4376,4377],{"class":197},"              /img/hero-1920w.webp 1920w",[130,4379,2789],{"class":193},[130,4381,4382,4384,4386,4388,4390],{"class":132,"line":1522},[130,4383,4321],{"class":2153},[130,4385,2160],{"class":162},[130,4387,2163],{"class":193},[130,4389,3987],{"class":197},[130,4391,2789],{"class":193},[130,4393,4394],{"class":132,"line":1530},[130,4395,4334],{"class":162},[130,4397,4398],{"class":132,"line":1536},[130,4399,4400],{"class":328},"    \u003C!-- PNG（フォールバック） -->\n",[130,4402,4403,4405],{"class":132,"line":1541},[130,4404,3010],{"class":162},[130,4406,2774],{"class":2149},[130,4408,4409,4412,4414,4416,4418],{"class":132,"line":1547},[130,4410,4411],{"class":2153},"      src",[130,4413,2160],{"class":162},[130,4415,2163],{"class":193},[130,4417,4175],{"class":197},[130,4419,2789],{"class":193},[130,4421,4422,4424,4426,4428],{"class":132,"line":1565},[130,4423,4298],{"class":2153},[130,4425,2160],{"class":162},[130,4427,2163],{"class":193},[130,4429,4188],{"class":197},[130,4431,4433],{"class":132,"line":4432},62,[130,4434,4435],{"class":197},"              /img/hero-1280w.png 1280w,\n",[130,4437,4439,4442],{"class":132,"line":4438},63,[130,4440,4441],{"class":197},"              /img/hero-1920w.png 1920w",[130,4443,2789],{"class":193},[130,4445,4447,4449,4451,4453,4455],{"class":132,"line":4446},64,[130,4448,4321],{"class":2153},[130,4450,2160],{"class":162},[130,4452,2163],{"class":193},[130,4454,3987],{"class":197},[130,4456,2789],{"class":193},[130,4458,4460,4463,4465,4467,4470],{"class":132,"line":4459},65,[130,4461,4462],{"class":2153},"      width",[130,4464,2160],{"class":162},[130,4466,2163],{"class":193},[130,4468,4469],{"class":197},"1920",[130,4471,2789],{"class":193},[130,4473,4475,4478,4480,4482,4485],{"class":132,"line":4474},66,[130,4476,4477],{"class":2153},"      height",[130,4479,2160],{"class":162},[130,4481,2163],{"class":193},[130,4483,4484],{"class":197},"1080",[130,4486,2789],{"class":193},[130,4488,4490,4493,4495,4497,4500],{"class":132,"line":4489},67,[130,4491,4492],{"class":2153},"      alt",[130,4494,2160],{"class":162},[130,4496,2163],{"class":193},[130,4498,4499],{"class":197},"メインビジュアル",[130,4501,2789],{"class":193},[130,4503,4505,4508,4510,4512,4514],{"class":132,"line":4504},68,[130,4506,4507],{"class":2153},"      fetchpriority",[130,4509,2160],{"class":162},[130,4511,2163],{"class":193},[130,4513,3854],{"class":197},[130,4515,2789],{"class":193},[130,4517,4519],{"class":132,"line":4518},69,[130,4520,4334],{"class":162},[130,4522,4524,4526,4528],{"class":132,"line":4523},70,[130,4525,3051],{"class":162},[130,4527,3440],{"class":2149},[130,4529,2170],{"class":162},[130,4531,4533,4535,4537],{"class":132,"line":4532},71,[130,4534,2193],{"class":162},[130,4536,4260],{"class":2149},[130,4538,2170],{"class":162},[11,4540,4542],{"id":4541},"nuxt-ではどうする","Nuxt ではどうする？",[16,4544,4545,4546,4549],{},"Nuxt には画像最適化モジュールとして ",[90,4547,4548],{},"@nuxt/image"," があります。",[2523,4551],{"url":4552},"https://image.nuxt.com/",[16,4554,4555],{},"画像最適化モジュールがどんなことをしてくれるかわかりやすいようにコードで比較してみます。",[76,4557,4559],{"id":4558},"html-と-nuxt-image-を比較する","HTML と Nuxt Image を比較する",[2566,4561,4562],{},[2569,4563,4564],{},"HTML",[83,4566,4567],{"className":2763,"code":3274,"language":2765,"meta":92,"style":92},[90,4568,4569,4575,4587,4597,4601,4605,4609,4615,4625,4629,4635,4647,4659,4667],{"__ignoreMap":92},[130,4570,4571,4573],{"class":132,"line":133},[130,4572,608],{"class":162},[130,4574,2774],{"class":2149},[130,4576,4577,4579,4581,4583,4585],{"class":132,"line":155},[130,4578,2779],{"class":2153},[130,4580,2160],{"class":162},[130,4582,2163],{"class":193},[130,4584,3293],{"class":197},[130,4586,2789],{"class":193},[130,4588,4589,4591,4593,4595],{"class":132,"line":169},[130,4590,2794],{"class":2153},[130,4592,2160],{"class":162},[130,4594,2163],{"class":193},[130,4596,3306],{"class":197},[130,4598,4599],{"class":132,"line":185},[130,4600,3154],{"class":197},[130,4602,4603],{"class":132,"line":207},[130,4604,3159],{"class":197},[130,4606,4607],{"class":132,"line":224},[130,4608,3164],{"class":197},[130,4610,4611,4613],{"class":132,"line":245},[130,4612,3323],{"class":197},[130,4614,2789],{"class":193},[130,4616,4617,4619,4621,4623],{"class":132,"line":265},[130,4618,3330],{"class":2153},[130,4620,2160],{"class":162},[130,4622,2163],{"class":193},[130,4624,3337],{"class":197},[130,4626,4627],{"class":132,"line":283},[130,4628,3342],{"class":197},[130,4630,4631,4633],{"class":132,"line":302},[130,4632,3347],{"class":197},[130,4634,2789],{"class":193},[130,4636,4637,4639,4641,4643,4645],{"class":132,"line":332},[130,4638,2823],{"class":2153},[130,4640,2160],{"class":162},[130,4642,2163],{"class":193},[130,4644,3360],{"class":197},[130,4646,2789],{"class":193},[130,4648,4649,4651,4653,4655,4657],{"class":132,"line":341},[130,4650,2837],{"class":2153},[130,4652,2160],{"class":162},[130,4654,2163],{"class":193},[130,4656,3373],{"class":197},[130,4658,2789],{"class":193},[130,4660,4661,4663,4665],{"class":132,"line":349},[130,4662,2850],{"class":2153},[130,4664,2160],{"class":162},[130,4666,3384],{"class":193},[130,4668,4669],{"class":132,"line":355},[130,4670,2170],{"class":162},[2566,4672,4673],{},[2569,4674,4675],{},"Nuxt Image",[83,4677,4679],{"className":2137,"code":4678,"language":2140,"meta":92,"style":92},"\u003CNuxtImg\n  src=\"/img/1600w.png\"\n  sizes=\"(min-width: 1200px) 836px,\n         (min-width: 768px) min(836px, calc(100vw - 300px - 2rem)),\n         calc(100vw - 2rem)\"\n  width=\"720\"\n  height=\"405\"\n  alt=\"\"\n/>\n",[90,4680,4681,4688,4700,4710,4714,4720,4732,4744,4752],{"__ignoreMap":92},[130,4682,4683,4685],{"class":132,"line":133},[130,4684,608],{"class":162},[130,4686,4687],{"class":2149},"NuxtImg\n",[130,4689,4690,4692,4694,4696,4698],{"class":132,"line":155},[130,4691,2779],{"class":2153},[130,4693,2160],{"class":162},[130,4695,2163],{"class":193},[130,4697,3228],{"class":197},[130,4699,2789],{"class":193},[130,4701,4702,4704,4706,4708],{"class":132,"line":169},[130,4703,3330],{"class":2153},[130,4705,2160],{"class":162},[130,4707,2163],{"class":193},[130,4709,3337],{"class":197},[130,4711,4712],{"class":132,"line":185},[130,4713,3342],{"class":197},[130,4715,4716,4718],{"class":132,"line":207},[130,4717,3347],{"class":197},[130,4719,2789],{"class":193},[130,4721,4722,4724,4726,4728,4730],{"class":132,"line":224},[130,4723,2823],{"class":2153},[130,4725,2160],{"class":162},[130,4727,2163],{"class":193},[130,4729,3360],{"class":197},[130,4731,2789],{"class":193},[130,4733,4734,4736,4738,4740,4742],{"class":132,"line":245},[130,4735,2837],{"class":2153},[130,4737,2160],{"class":162},[130,4739,2163],{"class":193},[130,4741,3373],{"class":197},[130,4743,2789],{"class":193},[130,4745,4746,4748,4750],{"class":132,"line":265},[130,4747,2850],{"class":2153},[130,4749,2160],{"class":162},[130,4751,3384],{"class":193},[130,4753,4754],{"class":132,"line":283},[130,4755,4756],{"class":180},"/>\n",[16,4758,4759,4760,4762,4763,4765,4766,4768],{},"高解像度の原本を渡して ",[90,4761,2945],{}," を指定すると Nuxt Image が ",[90,4764,3138],{}," を生成してくれます。",[35,4767],{},"\nこれにより、複数サイズの画像を手動で作成・配置する必要がなくなり記述もスッキリします。",[76,4770,4772,4775],{"id":4771},"nuxtpicture-を使って複数フォーマット配信",[90,4773,4774],{},"\u003CNuxtPicture>"," を使って複数フォーマット配信",[2523,4777],{"url":4778},"https://image.nuxt.com/usage/nuxt-picture",[16,4780,4781,4782,4784],{},"また、",[90,4783,4774],{}," を使用すれば複数フォーマットの配信とフォールバックの指定もできます。",[83,4786,4788],{"className":2137,"code":4787,"language":2140,"meta":92,"style":92},"\u003CNuxtPicture\n  provider=\"cloudinary\"\n  :src=\"_src\" // Cloudinaryに置いてある画像パス\n  format=\"avif,webp\"\n/>\n",[90,4789,4790,4797,4811,4836,4850],{"__ignoreMap":92},[130,4791,4792,4794],{"class":132,"line":133},[130,4793,608],{"class":162},[130,4795,4796],{"class":2149},"NuxtPicture\n",[130,4798,4799,4802,4804,4806,4809],{"class":132,"line":155},[130,4800,4801],{"class":2153},"  provider",[130,4803,2160],{"class":162},[130,4805,2163],{"class":193},[130,4807,4808],{"class":197},"cloudinary",[130,4810,2789],{"class":193},[130,4812,4813,4816,4819,4821,4824,4827,4829,4833],{"class":132,"line":169},[130,4814,4815],{"class":162},"  :",[130,4817,4818],{"class":2153},"src",[130,4820,2160],{"class":162},[130,4822,2163],{"class":4823},"s5sbo",[130,4825,4826],{"class":180},"_src",[130,4828,2163],{"class":4823},[130,4830,4832],{"class":4831},"sGgoF"," //",[130,4834,4835],{"class":2153}," Cloudinaryに置いてある画像パス\n",[130,4837,4838,4841,4843,4845,4848],{"class":132,"line":185},[130,4839,4840],{"class":2153},"  format",[130,4842,2160],{"class":162},[130,4844,2163],{"class":193},[130,4846,4847],{"class":197},"avif,webp",[130,4849,2789],{"class":193},[130,4851,4852],{"class":132,"line":207},[130,4853,4756],{"class":180},[16,4855,4856,4857,4859],{},"生成されるDOM",[35,4858],{},"\n（画像パスは抽象化しています）",[83,4861,4863],{"className":2763,"code":4862,"language":2765,"meta":92,"style":92},"\u003Cpicture>\n  // avif\n  \u003Csource type=\"image/avif\" sizes=\"(max-width: 640px) 320px, (max-width: 768px) 640px, (max-width: 1024px) 768px, (max-width: 1280px) 1024px, (max-width: 1536px) 1280px, 1536px\" srcset=\"/img/320w.png 320w, /img/640w.png 640w, /img/768w.png 768w, /img/1024w.png 1024w, /img/1280w.png 1280w, /img/1536w.png 1536w, /img/2048w.png 2048w, /img/2560w.png 2560w, /img/3072w.png 3072w\">\n  // webp\n  \u003Csource type=\"image/webp\" sizes=\"(max-width: 640px) 320px, (max-width: 768px) 640px, (max-width: 1024px) 768px, (max-width: 1280px) 1024px, (max-width: 1536px) 1280px, 1536px\" ssrcset=\"/img/320w.png 320w, /img/640w.png 640w, /img/768w.png 768w, /img/1024w.png 1024w, /img/1280w.png 1280w, /img/1536w.png 1536w, /img/2048w.png 2048w, /img/2560w.png 2560w, /img/3072w.png 3072w\">\n  // img (fallback)\n  \u003Cimg data-nuxt-pic=\"\" src=\"https://res.cloudinary.com/dyoyv8djx/image/upload/f_png,q_auto,w_3072/v1745236671/tsukiyama-blog/image-optimization/w1600_ar2ubh.png\" sizes=\"(max-width: 640px) 320px, (max-width: 768px) 640px, (max-width: 1024px) 768px, (max-width: 1280px) 1024px, (max-width: 1536px) 1280px, 1536px\" srcset=\"/img/320w.png 320w, /img/640w.png 640w, /img/768w.png 768w, /img/1024w.png 1024w, /img/1280w.png 1280w, /img/1536w.png 1536w, /img/2048w.png 2048w, /img/2560w.png 2560w, /img/3072w.png 3072w\">\n\u003C/picture>\n",[90,4864,4865,4873,4878,4920,4925,4964,4969,5017],{"__ignoreMap":92},[130,4866,4867,4869,4871],{"class":132,"line":133},[130,4868,608],{"class":162},[130,4870,3440],{"class":2149},[130,4872,2170],{"class":162},[130,4874,4875],{"class":132,"line":155},[130,4876,4877],{"class":180},"  // avif\n",[130,4879,4880,4882,4884,4886,4888,4890,4892,4894,4897,4899,4901,4904,4906,4909,4911,4913,4916,4918],{"class":132,"line":169},[130,4881,2989],{"class":162},[130,4883,3722],{"class":2149},[130,4885,496],{"class":2153},[130,4887,2160],{"class":162},[130,4889,2163],{"class":193},[130,4891,3466],{"class":197},[130,4893,2163],{"class":193},[130,4895,4896],{"class":2153}," sizes",[130,4898,2160],{"class":162},[130,4900,2163],{"class":193},[130,4902,4903],{"class":197},"(max-width: 640px) 320px, (max-width: 768px) 640px, (max-width: 1024px) 768px, (max-width: 1280px) 1024px, (max-width: 1536px) 1280px, 1536px",[130,4905,2163],{"class":193},[130,4907,4908],{"class":2153}," srcset",[130,4910,2160],{"class":162},[130,4912,2163],{"class":193},[130,4914,4915],{"class":197},"/img/320w.png 320w, /img/640w.png 640w, /img/768w.png 768w, /img/1024w.png 1024w, /img/1280w.png 1280w, /img/1536w.png 1536w, /img/2048w.png 2048w, /img/2560w.png 2560w, /img/3072w.png 3072w",[130,4917,2163],{"class":193},[130,4919,2170],{"class":162},[130,4921,4922],{"class":132,"line":185},[130,4923,4924],{"class":180},"  // webp\n",[130,4926,4927,4929,4931,4933,4935,4937,4939,4941,4943,4945,4947,4949,4951,4954,4956,4958,4960,4962],{"class":132,"line":207},[130,4928,2989],{"class":162},[130,4930,3722],{"class":2149},[130,4932,496],{"class":2153},[130,4934,2160],{"class":162},[130,4936,2163],{"class":193},[130,4938,3543],{"class":197},[130,4940,2163],{"class":193},[130,4942,4896],{"class":2153},[130,4944,2160],{"class":162},[130,4946,2163],{"class":193},[130,4948,4903],{"class":197},[130,4950,2163],{"class":193},[130,4952,4953],{"class":2153}," ssrcset",[130,4955,2160],{"class":162},[130,4957,2163],{"class":193},[130,4959,4915],{"class":197},[130,4961,2163],{"class":193},[130,4963,2170],{"class":162},[130,4965,4966],{"class":132,"line":224},[130,4967,4968],{"class":180},"  // img (fallback)\n",[130,4970,4971,4973,4975,4978,4980,4983,4986,4988,4990,4993,4995,4997,4999,5001,5003,5005,5007,5009,5011,5013,5015],{"class":132,"line":245},[130,4972,2989],{"class":162},[130,4974,2692],{"class":2149},[130,4976,4977],{"class":2153}," data-nuxt-pic",[130,4979,2160],{"class":162},[130,4981,4982],{"class":193},"\"\"",[130,4984,4985],{"class":2153}," src",[130,4987,2160],{"class":162},[130,4989,2163],{"class":193},[130,4991,4992],{"class":197},"https://res.cloudinary.com/dyoyv8djx/image/upload/f_png,q_auto,w_3072/v1745236671/tsukiyama-blog/image-optimization/w1600_ar2ubh.png",[130,4994,2163],{"class":193},[130,4996,4896],{"class":2153},[130,4998,2160],{"class":162},[130,5000,2163],{"class":193},[130,5002,4903],{"class":197},[130,5004,2163],{"class":193},[130,5006,4908],{"class":2153},[130,5008,2160],{"class":162},[130,5010,2163],{"class":193},[130,5012,4915],{"class":197},[130,5014,2163],{"class":193},[130,5016,2170],{"class":162},[130,5018,5019,5021,5023],{"class":132,"line":265},[130,5020,2193],{"class":162},[130,5022,3440],{"class":2149},[130,5024,2170],{"class":162},[16,5026,5027,5029],{},[90,5028,4675],{}," を使うと特に気にせずに一つの画像ソースから複数のサイズ、フォーマットで配信できるのでとても便利です。",[11,5031,5032],{"id":5032},"まとめ",[2566,5034,5035,5041,5047,5058,5064,5074,5081],{},[2569,5036,5037,5038],{},"最適化の対象は",[106,5039,5040],{},"ユーザーのデバイス",[2569,5042,5043,5044],{},"固定幅の画像は ",[106,5045,5046],{},"DPR ごとに画像サイズを変える",[2569,5048,5049,5050],{},"可変幅の画像は ",[106,5051,5052,5054,5055,5057],{},[90,5053,2941],{}," + ",[90,5056,2945],{}," を活用し、画像サイズを変える",[2569,5059,5060,5063],{},[106,5061,5062],{},"次世代フォーマット","を使いつつ、フォールバックで互換性を確保する",[2569,5065,5066,5067],{},"LCP 画像は ",[106,5068,5069,325,5071,5073],{},[90,5070,3846],{},[90,5072,3865],{}," で読み込みタイミングを制御",[2569,5075,5076,5077],{},"重要ではない画像は ",[106,5078,5079],{},[90,5080,3742],{},[2569,5082,5083,5084,5086,5087,5089],{},"Nuxt なら ",[90,5085,4548],{}," に任せると自動で ",[90,5088,3138],{}," ,フォーマット変換してくれて便利",[16,5091,5092],{},"今回はフロントエンド側でできることを整理しました。\nサーバー側での最適化や CDN 配信戦略など、よりインフラ寄りの話はまた別の機会に書いてみたいと思います。",[11,5094,5095],{"id":5095},"参考文献",[2523,5097],{"url":5098},"https://developer.mozilla.org/ja/docs/Web/HTML/Guides/Responsive_images",[2523,5100],{"url":5101},"https://stackoverflow.blog/2022/12/27/picture-perfect-images-with-the-modern-element/",[2523,5103],{"url":5104},"https://web.dev/articles/fetch-priority?hl=ja",[2420,5106,5107],{},"html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .s5sbo, html code.shiki .s5sbo{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#9ECBFF}html pre.shiki code .sGgoF, html code.shiki .sGgoF{--shiki-light:#90A4AE;--shiki-light-font-style:inherit;--shiki-default:#FFB1AF;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":92,"searchDepth":169,"depth":169,"links":5109},[5110,5111,5116,5117,5120,5126,5127,5132,5137,5138],{"id":2464,"depth":155,"text":2464},{"id":2487,"depth":155,"text":2487,"children":5112},[5113,5114,5115],{"id":2493,"depth":169,"text":2493},{"id":2505,"depth":169,"text":2505},{"id":2528,"depth":169,"text":2528},{"id":2557,"depth":155,"text":2558},{"id":2589,"depth":155,"text":2590,"children":5118},[5119],{"id":2877,"depth":169,"text":2878},{"id":2916,"depth":155,"text":2917,"children":5121},[5122,5123,5124,5125],{"id":3175,"depth":169,"text":3176},{"id":3209,"depth":169,"text":3210},{"id":3235,"depth":169,"text":3236},{"id":3263,"depth":169,"text":3263},{"id":3413,"depth":155,"text":3413},{"id":3736,"depth":155,"text":3736,"children":5128},[5129,5131],{"id":3739,"depth":169,"text":5130},"loading=\"lazy\" ＆ decoding=\"async\"",{"id":3835,"depth":169,"text":3836},{"id":4541,"depth":155,"text":4542,"children":5133},[5134,5135],{"id":4558,"depth":169,"text":4559},{"id":4771,"depth":169,"text":5136},"\u003CNuxtPicture> を使って複数フォーマット配信",{"id":5032,"depth":155,"text":5032},{"id":5095,"depth":155,"text":5095},"2025-08-17T00:00:00.000Z","フロントエンドでできる画像最適化の基本から Nuxt での実装方法までまとめました。","/avatar_orange_t1b2ky.webp",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1755351894/tsukiyama-blog/image-optimization/image-optimization_efkg8g.png","/tech/image-optimization",{"title":2459,"description":5140},"tech/image-optimization",[5148,5149,4675],"HTML5","Core Web Vitals","4lYe-x-iM74rc812ujrmKoaiZ0PlEvGuzvKAaHCsaIo",{"id":5152,"title":5153,"body":5154,"date":9716,"description":9717,"extension":381,"icon":2444,"meta":9718,"navigation":419,"ogImage":9719,"path":9720,"published":419,"publishedAt":2455,"seo":9721,"stem":9722,"tags":9723,"updatedAt":2455,"__hash__":9725},"tech/tech/google-maps-api.md","Nuxt で Google Maps API を使ってみる",{"type":8,"value":5155,"toc":9680},[5156,5158,5169,5180,5183,5187,5196,5202,5208,5215,5225,5229,5232,5246,5251,5267,5272,5279,5362,5366,5374,5377,5380,5383,5386,5410,5424,5496,5511,5560,5566,5572,5665,5668,5671,5678,5687,6198,6201,6207,6270,6273,6277,6280,6286,6293,6298,6887,6890,6966,6969,6971,6975,6978,6981,6988,7822,7825,7915,7918,7922,7925,7928,7931,7934,7940,7943,7949,7954,8916,8919,9643,9646,9649,9661,9664,9672,9674,9677],[11,5157,2464],{"id":2464},[16,5159,5160,5161,5164,5165,5168],{},"本記事は、",[90,5162,5163],{},"Nuxt"," で ",[90,5166,5167],{},"Google Maps API"," 使ってみた備忘録です。",[16,5170,5171,5172,5175,5176,5179],{},"Google Maps API は Google Map にまつわる様々な機能が扱えるが、今回は\n",[90,5173,5174],{},"Maps JavaScript API"," を使ったマップ表示と、",[90,5177,5178],{},"Directions API"," を使ったルート表示までを行います。",[11,5181,5182],{"id":5182},"準備",[76,5184,5186],{"id":5185},"api-key-作成","API Key 作成",[16,5188,5189,5192,5193,5195],{},[90,5190,5191],{},"Google Cloud"," のコンソールから API キーを作成します。",[35,5194],{},"\n使用するAPIは",[2566,5197,5198,5200],{},[2569,5199,5174],{},[2569,5201,5178],{},[16,5203,5204,5205,5207],{},"の2つです。",[35,5206],{},"\n上記 API を有効化し、API キーを作成してください。",[16,5209,5210,5211,5214],{},"作成した API キーを ",[90,5212,5213],{},".env"," で管理します。",[83,5216,5219],{"className":5217,"code":5218,"filename":5213,"language":5213,"meta":92,"style":92},"language-.env shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","NUXT_PUBLIC_SCRIPTS_GOOGLE_MAPS_API_KEY=\u003Cyour-api-key>\n",[90,5220,5221],{"__ignoreMap":92},[130,5222,5223],{"class":132,"line":133},[130,5224,5218],{},[76,5226,5228],{"id":5227},"map-id-作成","Map ID 作成",[2523,5230],{"url":5231},"https://console.cloud.google.com/google/maps-apis/overview",[16,5233,5234,5237,5238,5241,5242,5245],{},[90,5235,5236],{},"Google Maps Platform"," の オーバービューから ",[90,5239,5240],{},"マップマップ管理"," を選択し、",[90,5243,5244],{},"マップIDを作成"," へ進みます。",[16,5247,5248],{},[2692,5249],{"alt":92,"src":5250},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1753108496/tsukiyama-blog/google-maps-api/Group_43_pcsq8o.png",[16,5252,5253,5254,5257,5258,5260,2609,5263,5266],{},"名前と説明は任意の値を入力し、地図の種類を ",[90,5255,5256],{},"JavaScript"," を選択します。",[35,5259],{},[90,5261,5262],{},"ラスター",[90,5264,5265],{},"ベクター","は地図の形式の違いです、今回はラスターで問題ないです。",[16,5268,5269],{},[2692,5270],{"alt":92,"src":5271},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1753108498/tsukiyama-blog/google-maps-api/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-07-21_23.33.05_nzeyp3.png",[16,5273,5274,5275,5278],{},"環境変数として",[90,5276,5277],{},"runtimeConfig","に設定しておきます。",[83,5280,5283],{"className":123,"code":5281,"filename":5282,"language":126,"meta":92,"style":92},"export default defineNuxtConfig({\n runtimeConfig: {\n    public: {\n      googleMaps: {\n        mapId: '\u003Cyour-map-id>'\n      },\n    },\n ],\n})\n","nuxt.config.ts",[90,5284,5285,5298,5307,5316,5325,5339,5344,5349,5356],{"__ignoreMap":92},[130,5286,5287,5289,5291,5294,5296],{"class":132,"line":133},[130,5288,137],{"class":136},[130,5290,140],{"class":136},[130,5292,5293],{"class":143}," defineNuxtConfig",[130,5295,148],{"class":147},[130,5297,152],{"class":151},[130,5299,5300,5303,5305],{"class":132,"line":155},[130,5301,5302],{"class":158}," runtimeConfig",[130,5304,163],{"class":162},[130,5306,166],{"class":162},[130,5308,5309,5312,5314],{"class":132,"line":169},[130,5310,5311],{"class":158},"    public",[130,5313,163],{"class":162},[130,5315,166],{"class":162},[130,5317,5318,5321,5323],{"class":132,"line":185},[130,5319,5320],{"class":158},"      googleMaps",[130,5322,163],{"class":162},[130,5324,166],{"class":162},[130,5326,5327,5330,5332,5334,5337],{"class":132,"line":207},[130,5328,5329],{"class":158},"        mapId",[130,5331,163],{"class":162},[130,5333,194],{"class":193},[130,5335,5336],{"class":197},"\u003Cyour-map-id>",[130,5338,515],{"class":193},[130,5340,5341],{"class":132,"line":224},[130,5342,5343],{"class":162},"      },\n",[130,5345,5346],{"class":132,"line":245},[130,5347,5348],{"class":162},"    },\n",[130,5350,5351,5354],{"class":132,"line":265},[130,5352,5353],{"class":180}," ]",[130,5355,204],{"class":162},[130,5357,5358,5360],{"class":132,"line":283},[130,5359,358],{"class":162},[130,5361,338],{"class":180},[76,5363,5365],{"id":5364},"nuxt-scripts","Nuxt Scripts",[16,5367,5368,5370,5371,5373],{},[90,5369,5167],{}," を利用するにあたり、スクリプトの読み込みに ",[90,5372,5365],{}," を使用します。",[2523,5375],{"url":5376},"https://scripts.nuxt.com/",[2523,5378],{"url":5379},"https://scripts.nuxt.com/scripts/content/google-maps",[1576,5381,5382],{"id":5382},"インストール",[16,5384,5385],{},"Nuxi を用いてインストールします。",[83,5387,5391],{"className":5388,"code":5389,"language":5390,"meta":92,"style":92},"language-bash shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","npx nuxi@latest module add scripts\n","bash",[90,5392,5393],{"__ignoreMap":92},[130,5394,5395,5398,5401,5404,5407],{"class":132,"line":133},[130,5396,5397],{"class":570},"npx",[130,5399,5400],{"class":197}," nuxi@latest",[130,5402,5403],{"class":197}," module",[130,5405,5406],{"class":197}," add",[130,5408,5409],{"class":197}," scripts\n",[16,5411,5412,5415,5416,5419,5420,5423],{},[90,5413,5414],{},"Google Maps"," を ",[90,5417,5418],{},"TypeScript"," で扱うために ",[90,5421,5422],{},"@types/google.maps"," パッケージをインストールします。",[5425,5426,5427,5446,5462,5479],"code-group",{},[83,5428,5431],{"className":5388,"code":5429,"filename":5430,"language":5390,"meta":92,"style":92},"pnpm add -D @types/google.maps\n","pnpm",[90,5432,5433],{"__ignoreMap":92},[130,5434,5435,5437,5439,5443],{"class":132,"line":133},[130,5436,5430],{"class":570},[130,5438,5406],{"class":197},[130,5440,5442],{"class":5441},"spR0o"," -D",[130,5444,5445],{"class":197}," @types/google.maps\n",[83,5447,5450],{"className":5388,"code":5448,"filename":5449,"language":5390,"meta":92,"style":92},"yarn add -D @types/google.maps\n","yarn",[90,5451,5452],{"__ignoreMap":92},[130,5453,5454,5456,5458,5460],{"class":132,"line":133},[130,5455,5449],{"class":570},[130,5457,5406],{"class":197},[130,5459,5442],{"class":5441},[130,5461,5445],{"class":197},[83,5463,5466],{"className":5388,"code":5464,"filename":5465,"language":5390,"meta":92,"style":92},"npm install -D @types/google.maps\n","npm",[90,5467,5468],{"__ignoreMap":92},[130,5469,5470,5472,5475,5477],{"class":132,"line":133},[130,5471,5465],{"class":570},[130,5473,5474],{"class":197}," install",[130,5476,5442],{"class":5441},[130,5478,5445],{"class":197},[83,5480,5483],{"className":5388,"code":5481,"filename":5482,"language":5390,"meta":92,"style":92},"bun add -d @types/google.maps\n","bun",[90,5484,5485],{"__ignoreMap":92},[130,5486,5487,5489,5491,5494],{"class":132,"line":133},[130,5488,5482],{"class":570},[130,5490,5406],{"class":197},[130,5492,5493],{"class":5441}," -d",[130,5495,5445],{"class":197},[16,5497,5498,5510],{},[90,5499,5502,5505,5507],{"className":5500,"language":5501,"style":92},"language-ts-type shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","ts-type",[130,5503,5504],{"class":570},"tsconfig",[130,5506,235],{"class":162},[130,5508,5509],{"class":570},"json"," で読み込むようにしておきます。",[83,5512,5517],{"className":5513,"code":5514,"filename":5515,"language":5516,"meta":92,"style":92},"language-diff shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","{\n  // https://nuxt.com/docs/guide/concepts/typescript\n  \"extends\": \"./.nuxt/tsconfig.json\",\n+  \"compilerOptions\": {\n+  \"types\": [\"google.maps\"]\n+ }\n}\n","tsconfig.json","diff",[90,5518,5519,5523,5528,5533,5543,5550,5556],{"__ignoreMap":92},[130,5520,5521],{"class":132,"line":133},[130,5522,152],{"class":180},[130,5524,5525],{"class":132,"line":155},[130,5526,5527],{"class":180},"  // https://nuxt.com/docs/guide/concepts/typescript\n",[130,5529,5530],{"class":132,"line":169},[130,5531,5532],{"class":180},"  \"extends\": \"./.nuxt/tsconfig.json\",\n",[130,5534,5535,5539],{"class":132,"line":185},[130,5536,5538],{"class":5537},"s08Pv","+",[130,5540,5542],{"class":5541},"sBpHv","  \"compilerOptions\": {\n",[130,5544,5545,5547],{"class":132,"line":207},[130,5546,5538],{"class":5537},[130,5548,5549],{"class":5541},"  \"types\": [\"google.maps\"]\n",[130,5551,5552,5554],{"class":132,"line":224},[130,5553,5538],{"class":5537},[130,5555,1998],{"class":5541},[130,5557,5558],{"class":132,"line":245},[130,5559,686],{"class":180},[1576,5561,5563],{"id":5562},"nuxtconfig",[90,5564,5565],{},"nuxt.config",[16,5567,5568,5569,5571],{},"ドキュメントに従って API キーを環境変数として定義します\n（",[90,5570,5213],{},"で定義しているのでここでは空文字）",[83,5573,5575],{"className":123,"code":5574,"filename":5282,"language":126,"meta":92,"style":92},"export default defineNuxtConfig({\n runtimeConfig: {\n    public: {\n      // ...other prop\n      scripts: {\n        googleMaps: {\n          apiKey: '',\n        }\n      },\n    },\n ],\n})\n",[90,5576,5577,5589,5597,5605,5610,5619,5628,5640,5645,5649,5653,5659],{"__ignoreMap":92},[130,5578,5579,5581,5583,5585,5587],{"class":132,"line":133},[130,5580,137],{"class":136},[130,5582,140],{"class":136},[130,5584,5293],{"class":143},[130,5586,148],{"class":147},[130,5588,152],{"class":151},[130,5590,5591,5593,5595],{"class":132,"line":155},[130,5592,5302],{"class":158},[130,5594,163],{"class":162},[130,5596,166],{"class":162},[130,5598,5599,5601,5603],{"class":132,"line":169},[130,5600,5311],{"class":158},[130,5602,163],{"class":162},[130,5604,166],{"class":162},[130,5606,5607],{"class":132,"line":185},[130,5608,5609],{"class":328},"      // ...other prop\n",[130,5611,5612,5615,5617],{"class":132,"line":207},[130,5613,5614],{"class":158},"      scripts",[130,5616,163],{"class":162},[130,5618,166],{"class":162},[130,5620,5621,5624,5626],{"class":132,"line":224},[130,5622,5623],{"class":158},"        googleMaps",[130,5625,163],{"class":162},[130,5627,166],{"class":162},[130,5629,5630,5633,5635,5638],{"class":132,"line":245},[130,5631,5632],{"class":158},"          apiKey",[130,5634,163],{"class":162},[130,5636,5637],{"class":193}," ''",[130,5639,204],{"class":162},[130,5641,5642],{"class":132,"line":265},[130,5643,5644],{"class":162},"        }\n",[130,5646,5647],{"class":132,"line":283},[130,5648,5343],{"class":162},[130,5650,5651],{"class":132,"line":302},[130,5652,5348],{"class":162},[130,5654,5655,5657],{"class":132,"line":332},[130,5656,5353],{"class":180},[130,5658,204],{"class":162},[130,5660,5661,5663],{"class":132,"line":341},[130,5662,358],{"class":162},[130,5664,338],{"class":180},[11,5666,5667],{"id":5667},"地図を表示する",[16,5669,5670],{},"まずは、地図を表示してみるところまで進めます。",[76,5672,5674,5677],{"id":5673},"basicmap-コンポーネント作成",[90,5675,5676],{},"BasicMap"," コンポーネント作成",[16,5679,5680,5683,5684,5686],{},[90,5681,5682],{},"~/components/map/BasicMap.vue","を作成して、そこに ",[90,5685,5167],{}," を呼ぶように作ります。",[83,5688,5690],{"className":2137,"code":5689,"filename":5682,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\ntype Position = { lat: number, lng: number }\n\nconst props = defineProps\u003C{\n  position: Position\n  zoom?: number\n}>()\n\nconst config = useRuntimeConfig()\n\nconst mapRef = ref\u003CHTMLElement | null>(null)\n\nconst { onLoaded } = useScriptGoogleMaps()\n\nonMounted(() => {\n  // Google Maps の読み込みが完了したら実行\n  onLoaded(async (instance) => {\n    if (!mapRef.value) {\n      return\n    }\n\n    // Google Maps API モジュールを取得\n    const maps = await instance.maps\n    // MapsLibrary から Map クラスを取得\n    const { Map } = await maps.importLibrary('maps') as google.maps.MapsLibrary\n\n    // Google Map のインスタンスを生成して DOM に描画\n    new Map(mapRef.value, {\n      center: props.position,\n      zoom: props.zoom ?? 8,\n      mapId: config.public.googleMaps.mapId,\n    })\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv\n    ref=\"mapRef\"\n    class=\"w-full aspect-video\"\n  />\n\u003C/template>\n",[90,5691,5692,5713,5743,5747,5762,5772,5783,5790,5794,5808,5812,5842,5846,5864,5868,5881,5886,5906,5927,5932,5936,5940,5945,5965,5970,6018,6022,6027,6046,6062,6084,6110,6116,6122,6128,6136,6140,6148,6155,6168,6182,6190],{"__ignoreMap":92},[130,5693,5694,5696,5699,5701,5703,5705,5707,5709,5711],{"class":132,"line":133},[130,5695,608],{"class":162},[130,5697,5698],{"class":2149},"script",[130,5700,2154],{"class":2153},[130,5702,2157],{"class":2153},[130,5704,2160],{"class":162},[130,5706,2163],{"class":193},[130,5708,126],{"class":197},[130,5710,2163],{"class":193},[130,5712,2170],{"class":162},[130,5714,5715,5717,5720,5722,5724,5727,5729,5732,5734,5737,5739,5741],{"class":132,"line":155},[130,5716,3726],{"class":546},[130,5718,5719],{"class":570}," Position",[130,5721,555],{"class":554},[130,5723,499],{"class":162},[130,5725,5726],{"class":1925}," lat",[130,5728,163],{"class":554},[130,5730,5731],{"class":580}," number",[130,5733,325],{"class":162},[130,5735,5736],{"class":1925}," lng",[130,5738,163],{"class":554},[130,5740,5731],{"class":580},[130,5742,1998],{"class":162},[130,5744,5745],{"class":132,"line":169},[130,5746,420],{"emptyLinePlaceholder":419},[130,5748,5749,5751,5754,5756,5759],{"class":132,"line":185},[130,5750,1012],{"class":546},[130,5752,5753],{"class":597}," props",[130,5755,555],{"class":554},[130,5757,5758],{"class":143}," defineProps",[130,5760,5761],{"class":162},"\u003C{\n",[130,5763,5764,5767,5769],{"class":132,"line":207},[130,5765,5766],{"class":1925},"  position",[130,5768,163],{"class":554},[130,5770,5771],{"class":570}," Position\n",[130,5773,5774,5777,5780],{"class":132,"line":224},[130,5775,5776],{"class":1925},"  zoom",[130,5778,5779],{"class":554},"?:",[130,5781,5782],{"class":580}," number\n",[130,5784,5785,5788],{"class":132,"line":245},[130,5786,5787],{"class":162},"}>",[130,5789,669],{"class":180},[130,5791,5792],{"class":132,"line":265},[130,5793,420],{"emptyLinePlaceholder":419},[130,5795,5796,5798,5801,5803,5806],{"class":132,"line":283},[130,5797,1012],{"class":546},[130,5799,5800],{"class":597}," config",[130,5802,555],{"class":554},[130,5804,5805],{"class":143}," useRuntimeConfig",[130,5807,669],{"class":180},[130,5809,5810],{"class":132,"line":302},[130,5811,420],{"emptyLinePlaceholder":419},[130,5813,5814,5816,5819,5821,5824,5826,5829,5831,5833,5835,5837,5840],{"class":132,"line":332},[130,5815,1012],{"class":546},[130,5817,5818],{"class":597}," mapRef",[130,5820,555],{"class":554},[130,5822,5823],{"class":143}," ref",[130,5825,608],{"class":162},[130,5827,5828],{"class":570},"HTMLElement",[130,5830,2061],{"class":554},[130,5832,1171],{"class":580},[130,5834,618],{"class":162},[130,5836,148],{"class":180},[130,5838,5839],{"class":1170},"null",[130,5841,338],{"class":180},[130,5843,5844],{"class":132,"line":341},[130,5845,420],{"emptyLinePlaceholder":419},[130,5847,5848,5850,5852,5855,5857,5859,5862],{"class":132,"line":349},[130,5849,1012],{"class":546},[130,5851,499],{"class":162},[130,5853,5854],{"class":597}," onLoaded",[130,5856,505],{"class":162},[130,5858,555],{"class":554},[130,5860,5861],{"class":143}," useScriptGoogleMaps",[130,5863,669],{"class":180},[130,5865,5866],{"class":132,"line":355},[130,5867,420],{"emptyLinePlaceholder":419},[130,5869,5870,5873,5875,5877,5879],{"class":132,"line":783},[130,5871,5872],{"class":143},"onMounted",[130,5874,148],{"class":180},[130,5876,260],{"class":162},[130,5878,587],{"class":546},[130,5880,166],{"class":162},[130,5882,5883],{"class":132,"line":793},[130,5884,5885],{"class":328},"  // Google Maps の読み込みが完了したら実行\n",[130,5887,5888,5891,5893,5895,5897,5900,5902,5904],{"class":132,"line":798},[130,5889,5890],{"class":143},"  onLoaded",[130,5892,148],{"class":158},[130,5894,1622],{"class":546},[130,5896,561],{"class":162},[130,5898,5899],{"class":564},"instance",[130,5901,584],{"class":162},[130,5903,587],{"class":546},[130,5905,166],{"class":162},[130,5907,5908,5911,5913,5915,5918,5920,5923,5925],{"class":132,"line":806},[130,5909,5910],{"class":136},"    if",[130,5912,561],{"class":158},[130,5914,1432],{"class":554},[130,5916,5917],{"class":180},"mapRef",[130,5919,235],{"class":162},[130,5921,5922],{"class":180},"value",[130,5924,1174],{"class":158},[130,5926,152],{"class":162},[130,5928,5929],{"class":132,"line":1073},[130,5930,5931],{"class":136},"      return\n",[130,5933,5934],{"class":132,"line":1086},[130,5935,2105],{"class":162},[130,5937,5938],{"class":132,"line":1092},[130,5939,420],{"emptyLinePlaceholder":419},[130,5941,5942],{"class":132,"line":1128},[130,5943,5944],{"class":328},"    // Google Maps API モジュールを取得\n",[130,5946,5947,5950,5953,5955,5957,5960,5962],{"class":132,"line":1151},[130,5948,5949],{"class":546},"    const",[130,5951,5952],{"class":597}," maps",[130,5954,555],{"class":554},[130,5956,603],{"class":136},[130,5958,5959],{"class":180}," instance",[130,5961,235],{"class":162},[130,5963,5964],{"class":180},"maps\n",[130,5966,5967],{"class":132,"line":1156},[130,5968,5969],{"class":328},"    // MapsLibrary から Map クラスを取得\n",[130,5971,5972,5974,5976,5979,5981,5983,5985,5987,5989,5992,5994,5996,5999,6001,6003,6006,6009,6011,6013,6015],{"class":132,"line":1179},[130,5973,5949],{"class":546},[130,5975,499],{"class":162},[130,5977,5978],{"class":597}," Map",[130,5980,505],{"class":162},[130,5982,555],{"class":554},[130,5984,603],{"class":136},[130,5986,5952],{"class":180},[130,5988,235],{"class":162},[130,5990,5991],{"class":143},"importLibrary",[130,5993,148],{"class":158},[130,5995,201],{"class":193},[130,5997,5998],{"class":197},"maps",[130,6000,201],{"class":193},[130,6002,1174],{"class":158},[130,6004,6005],{"class":136},"as",[130,6007,6008],{"class":570}," google",[130,6010,235],{"class":162},[130,6012,5998],{"class":570},[130,6014,235],{"class":162},[130,6016,6017],{"class":570},"MapsLibrary\n",[130,6019,6020],{"class":132,"line":1188},[130,6021,420],{"emptyLinePlaceholder":419},[130,6023,6024],{"class":132,"line":1193},[130,6025,6026],{"class":328},"    // Google Map のインスタンスを生成して DOM に描画\n",[130,6028,6029,6032,6034,6036,6038,6040,6042,6044],{"class":132,"line":1198},[130,6030,6031],{"class":554},"    new",[130,6033,5978],{"class":143},[130,6035,148],{"class":158},[130,6037,5917],{"class":180},[130,6039,235],{"class":162},[130,6041,5922],{"class":180},[130,6043,325],{"class":162},[130,6045,166],{"class":162},[130,6047,6048,6051,6053,6055,6057,6060],{"class":132,"line":1222},[130,6049,6050],{"class":158},"      center",[130,6052,163],{"class":162},[130,6054,5753],{"class":180},[130,6056,235],{"class":162},[130,6058,6059],{"class":180},"position",[130,6061,204],{"class":162},[130,6063,6064,6067,6069,6071,6073,6076,6079,6082],{"class":132,"line":1227},[130,6065,6066],{"class":158},"      zoom",[130,6068,163],{"class":162},[130,6070,5753],{"class":180},[130,6072,235],{"class":162},[130,6074,6075],{"class":180},"zoom",[130,6077,6078],{"class":554}," ??",[130,6080,6081],{"class":2349}," 8",[130,6083,204],{"class":162},[130,6085,6086,6089,6091,6093,6095,6098,6100,6103,6105,6108],{"class":132,"line":1232},[130,6087,6088],{"class":158},"      mapId",[130,6090,163],{"class":162},[130,6092,5800],{"class":180},[130,6094,235],{"class":162},[130,6096,6097],{"class":180},"public",[130,6099,235],{"class":162},[130,6101,6102],{"class":180},"googleMaps",[130,6104,235],{"class":162},[130,6106,6107],{"class":180},"mapId",[130,6109,204],{"class":162},[130,6111,6112,6114],{"class":132,"line":1237},[130,6113,344],{"class":162},[130,6115,338],{"class":158},[130,6117,6118,6120],{"class":132,"line":1243},[130,6119,1981],{"class":162},[130,6121,338],{"class":158},[130,6123,6124,6126],{"class":132,"line":1256},[130,6125,358],{"class":162},[130,6127,338],{"class":180},[130,6129,6130,6132,6134],{"class":132,"line":1268},[130,6131,2193],{"class":162},[130,6133,5698],{"class":2149},[130,6135,2170],{"class":162},[130,6137,6138],{"class":132,"line":1273},[130,6139,420],{"emptyLinePlaceholder":419},[130,6141,6142,6144,6146],{"class":132,"line":1301},[130,6143,608],{"class":162},[130,6145,2130],{"class":2149},[130,6147,2170],{"class":162},[130,6149,6150,6152],{"class":132,"line":1320},[130,6151,2989],{"class":162},[130,6153,6154],{"class":2149},"div\n",[130,6156,6157,6160,6162,6164,6166],{"class":132,"line":1325},[130,6158,6159],{"class":2153},"    ref",[130,6161,2160],{"class":162},[130,6163,2163],{"class":193},[130,6165,5917],{"class":197},[130,6167,2789],{"class":193},[130,6169,6170,6173,6175,6177,6180],{"class":132,"line":1344},[130,6171,6172],{"class":2153},"    class",[130,6174,2160],{"class":162},[130,6176,2163],{"class":193},[130,6178,6179],{"class":197},"w-full aspect-video",[130,6181,2789],{"class":193},[130,6183,6184,6188],{"class":132,"line":1349},[130,6185,6187],{"class":6186},"sDdkT","  /",[130,6189,2170],{"class":162},[130,6191,6192,6194,6196],{"class":132,"line":1354},[130,6193,2193],{"class":162},[130,6195,2130],{"class":2149},[130,6197,2170],{"class":162},[76,6199,6200],{"id":6200},"コンポーネントを呼ぶ側",[16,6202,6203,6206],{},[90,6204,6205],{},"props"," として 緯度・経度、ズーム値を渡します。",[83,6208,6211],{"className":2137,"code":6209,"filename":6210,"language":2140,"meta":92,"style":92},"// 皇居の緯度経度を渡す\n\u003CBasicMap :position=\"{ lat: 35.685355, lng: 139.753144 }\" :zoom=\"14\" />\n","index.vue",[90,6212,6213,6218],{"__ignoreMap":92},[130,6214,6215],{"class":132,"line":133},[130,6216,6217],{"class":180},"// 皇居の緯度経度を渡す\n",[130,6219,6220,6222,6224,6226,6228,6230,6232,6234,6236,6238,6241,6243,6245,6247,6250,6252,6254,6256,6258,6260,6262,6265,6267],{"class":132,"line":155},[130,6221,608],{"class":162},[130,6223,5676],{"class":2149},[130,6225,1217],{"class":162},[130,6227,6059],{"class":2153},[130,6229,2160],{"class":162},[130,6231,2163],{"class":4823},[130,6233,2341],{"class":162},[130,6235,5726],{"class":158},[130,6237,163],{"class":162},[130,6239,6240],{"class":2349}," 35.685355",[130,6242,325],{"class":162},[130,6244,5736],{"class":158},[130,6246,163],{"class":162},[130,6248,6249],{"class":2349}," 139.753144",[130,6251,505],{"class":162},[130,6253,2163],{"class":4823},[130,6255,1217],{"class":162},[130,6257,6075],{"class":2153},[130,6259,2160],{"class":162},[130,6261,2163],{"class":4823},[130,6263,6264],{"class":2349},"14",[130,6266,2163],{"class":4823},[130,6268,6269],{"class":162}," />\n",[76,6271,6272],{"id":6272},"画面表示はこんな感じ",[6274,6275],"basic-map",{":position":6276,":zoom":6264},"{\"lat\":35.685355,\"lng\":139.753144}",[11,6278,6279],{"id":6279},"地図にマーカーを追加する",[16,6281,6282,6283,6285],{},"少し手を加えて、地図上の ",[90,6284,6059],{}," の位置にマーカーを表示してみます。",[76,6287,6289,6292],{"id":6288},"basicmapvue-コンポーネント修正",[90,6290,6291],{},"BasicMap.vue"," コンポーネント修正",[16,6294,6295,6297],{},[90,6296,6291],{}," を修正します。",[83,6299,6302],{"className":2137,"code":6300,"filename":5682,"highlights":6301,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\ntype Position = { lat: number, lng: number }\n\nconst props = defineProps\u003C{\n  position: Position\n  zoom?: number\n  // マーカー表示を制御する props\n  enableMarker?: boolean\n}>()\n\nconst config = useRuntimeConfig()\n\nconst mapRef = ref\u003CHTMLElement | null>(null)\n\nconst { onLoaded } = useScriptGoogleMaps()\n\nonMounted(() => {\n  onLoaded(async (instance) => {\n    if (!mapRef.value) {\n      return\n    }\n\n    const maps = await instance.maps\n    const { Map } = await maps.importLibrary('maps') as google.maps.MapsLibrary\n    // マーカーのクラスを取得\n    const { AdvancedMarkerElement } = await maps.importLibrary('marker') as google.maps.MarkerLibrary\n\n    const map = new Map(mapRef.value, {\n      center: props.position,\n      zoom: props.zoom ?? 8,\n      mapId: config.public.googleMaps.mapId,\n    })\n\n    // enableMarker が true の場合マーカーを表示\n    if (props.enableMarker) {\n      new AdvancedMarkerElement({\n        map,\n        position: props.position,\n      })\n    }\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv\n    ref=\"mapRef\"\n    class=\"w-full aspect-video\"\n  />\n\u003C/template>\n",[245,265,1179,1188,1256,1268,1273,1301,1320,1325,1344],[90,6303,6304,6324,6350,6354,6366,6374,6382,6389,6399,6405,6409,6421,6425,6451,6455,6471,6475,6487,6505,6523,6527,6531,6535,6551,6593,6599,6645,6649,6675,6689,6707,6729,6735,6739,6745,6763,6775,6783,6799,6806,6811,6817,6823,6831,6835,6843,6849,6861,6873,6879],{"__ignoreMap":92},[130,6305,6306,6308,6310,6312,6314,6316,6318,6320,6322],{"class":132,"line":133},[130,6307,608],{"class":162},[130,6309,5698],{"class":2149},[130,6311,2154],{"class":2153},[130,6313,2157],{"class":2153},[130,6315,2160],{"class":162},[130,6317,2163],{"class":193},[130,6319,126],{"class":197},[130,6321,2163],{"class":193},[130,6323,2170],{"class":162},[130,6325,6326,6328,6330,6332,6334,6336,6338,6340,6342,6344,6346,6348],{"class":132,"line":155},[130,6327,3726],{"class":546},[130,6329,5719],{"class":570},[130,6331,555],{"class":554},[130,6333,499],{"class":162},[130,6335,5726],{"class":1925},[130,6337,163],{"class":554},[130,6339,5731],{"class":580},[130,6341,325],{"class":162},[130,6343,5736],{"class":1925},[130,6345,163],{"class":554},[130,6347,5731],{"class":580},[130,6349,1998],{"class":162},[130,6351,6352],{"class":132,"line":169},[130,6353,420],{"emptyLinePlaceholder":419},[130,6355,6356,6358,6360,6362,6364],{"class":132,"line":185},[130,6357,1012],{"class":546},[130,6359,5753],{"class":597},[130,6361,555],{"class":554},[130,6363,5758],{"class":143},[130,6365,5761],{"class":162},[130,6367,6368,6370,6372],{"class":132,"line":207},[130,6369,5766],{"class":1925},[130,6371,163],{"class":554},[130,6373,5771],{"class":570},[130,6375,6376,6378,6380],{"class":132,"line":224},[130,6377,5776],{"class":1925},[130,6379,5779],{"class":554},[130,6381,5782],{"class":580},[130,6383,6386],{"class":6384,"line":245},[132,6385],"highlight",[130,6387,6388],{"class":328},"  // マーカー表示を制御する props\n",[130,6390,6392,6395,6397],{"class":6391,"line":265},[132,6385],[130,6393,6394],{"class":1925},"  enableMarker",[130,6396,5779],{"class":554},[130,6398,1388],{"class":580},[130,6400,6401,6403],{"class":132,"line":283},[130,6402,5787],{"class":162},[130,6404,669],{"class":180},[130,6406,6407],{"class":132,"line":302},[130,6408,420],{"emptyLinePlaceholder":419},[130,6410,6411,6413,6415,6417,6419],{"class":132,"line":332},[130,6412,1012],{"class":546},[130,6414,5800],{"class":597},[130,6416,555],{"class":554},[130,6418,5805],{"class":143},[130,6420,669],{"class":180},[130,6422,6423],{"class":132,"line":341},[130,6424,420],{"emptyLinePlaceholder":419},[130,6426,6427,6429,6431,6433,6435,6437,6439,6441,6443,6445,6447,6449],{"class":132,"line":349},[130,6428,1012],{"class":546},[130,6430,5818],{"class":597},[130,6432,555],{"class":554},[130,6434,5823],{"class":143},[130,6436,608],{"class":162},[130,6438,5828],{"class":570},[130,6440,2061],{"class":554},[130,6442,1171],{"class":580},[130,6444,618],{"class":162},[130,6446,148],{"class":180},[130,6448,5839],{"class":1170},[130,6450,338],{"class":180},[130,6452,6453],{"class":132,"line":355},[130,6454,420],{"emptyLinePlaceholder":419},[130,6456,6457,6459,6461,6463,6465,6467,6469],{"class":132,"line":783},[130,6458,1012],{"class":546},[130,6460,499],{"class":162},[130,6462,5854],{"class":597},[130,6464,505],{"class":162},[130,6466,555],{"class":554},[130,6468,5861],{"class":143},[130,6470,669],{"class":180},[130,6472,6473],{"class":132,"line":793},[130,6474,420],{"emptyLinePlaceholder":419},[130,6476,6477,6479,6481,6483,6485],{"class":132,"line":798},[130,6478,5872],{"class":143},[130,6480,148],{"class":180},[130,6482,260],{"class":162},[130,6484,587],{"class":546},[130,6486,166],{"class":162},[130,6488,6489,6491,6493,6495,6497,6499,6501,6503],{"class":132,"line":806},[130,6490,5890],{"class":143},[130,6492,148],{"class":158},[130,6494,1622],{"class":546},[130,6496,561],{"class":162},[130,6498,5899],{"class":564},[130,6500,584],{"class":162},[130,6502,587],{"class":546},[130,6504,166],{"class":162},[130,6506,6507,6509,6511,6513,6515,6517,6519,6521],{"class":132,"line":1073},[130,6508,5910],{"class":136},[130,6510,561],{"class":158},[130,6512,1432],{"class":554},[130,6514,5917],{"class":180},[130,6516,235],{"class":162},[130,6518,5922],{"class":180},[130,6520,1174],{"class":158},[130,6522,152],{"class":162},[130,6524,6525],{"class":132,"line":1086},[130,6526,5931],{"class":136},[130,6528,6529],{"class":132,"line":1092},[130,6530,2105],{"class":162},[130,6532,6533],{"class":132,"line":1128},[130,6534,420],{"emptyLinePlaceholder":419},[130,6536,6537,6539,6541,6543,6545,6547,6549],{"class":132,"line":1151},[130,6538,5949],{"class":546},[130,6540,5952],{"class":597},[130,6542,555],{"class":554},[130,6544,603],{"class":136},[130,6546,5959],{"class":180},[130,6548,235],{"class":162},[130,6550,5964],{"class":180},[130,6552,6553,6555,6557,6559,6561,6563,6565,6567,6569,6571,6573,6575,6577,6579,6581,6583,6585,6587,6589,6591],{"class":132,"line":1156},[130,6554,5949],{"class":546},[130,6556,499],{"class":162},[130,6558,5978],{"class":597},[130,6560,505],{"class":162},[130,6562,555],{"class":554},[130,6564,603],{"class":136},[130,6566,5952],{"class":180},[130,6568,235],{"class":162},[130,6570,5991],{"class":143},[130,6572,148],{"class":158},[130,6574,201],{"class":193},[130,6576,5998],{"class":197},[130,6578,201],{"class":193},[130,6580,1174],{"class":158},[130,6582,6005],{"class":136},[130,6584,6008],{"class":570},[130,6586,235],{"class":162},[130,6588,5998],{"class":570},[130,6590,235],{"class":162},[130,6592,6017],{"class":570},[130,6594,6596],{"class":6595,"line":1179},[132,6385],[130,6597,6598],{"class":328},"    // マーカーのクラスを取得\n",[130,6600,6602,6604,6606,6609,6611,6613,6615,6617,6619,6621,6623,6625,6628,6630,6632,6634,6636,6638,6640,6642],{"class":6601,"line":1188},[132,6385],[130,6603,5949],{"class":546},[130,6605,499],{"class":162},[130,6607,6608],{"class":597}," AdvancedMarkerElement",[130,6610,505],{"class":162},[130,6612,555],{"class":554},[130,6614,603],{"class":136},[130,6616,5952],{"class":180},[130,6618,235],{"class":162},[130,6620,5991],{"class":143},[130,6622,148],{"class":158},[130,6624,201],{"class":193},[130,6626,6627],{"class":197},"marker",[130,6629,201],{"class":193},[130,6631,1174],{"class":158},[130,6633,6005],{"class":136},[130,6635,6008],{"class":570},[130,6637,235],{"class":162},[130,6639,5998],{"class":570},[130,6641,235],{"class":162},[130,6643,6644],{"class":570},"MarkerLibrary\n",[130,6646,6647],{"class":132,"line":1193},[130,6648,420],{"emptyLinePlaceholder":419},[130,6650,6651,6653,6656,6658,6661,6663,6665,6667,6669,6671,6673],{"class":132,"line":1198},[130,6652,5949],{"class":546},[130,6654,6655],{"class":597}," map",[130,6657,555],{"class":554},[130,6659,6660],{"class":554}," new",[130,6662,5978],{"class":143},[130,6664,148],{"class":158},[130,6666,5917],{"class":180},[130,6668,235],{"class":162},[130,6670,5922],{"class":180},[130,6672,325],{"class":162},[130,6674,166],{"class":162},[130,6676,6677,6679,6681,6683,6685,6687],{"class":132,"line":1222},[130,6678,6050],{"class":158},[130,6680,163],{"class":162},[130,6682,5753],{"class":180},[130,6684,235],{"class":162},[130,6686,6059],{"class":180},[130,6688,204],{"class":162},[130,6690,6691,6693,6695,6697,6699,6701,6703,6705],{"class":132,"line":1227},[130,6692,6066],{"class":158},[130,6694,163],{"class":162},[130,6696,5753],{"class":180},[130,6698,235],{"class":162},[130,6700,6075],{"class":180},[130,6702,6078],{"class":554},[130,6704,6081],{"class":2349},[130,6706,204],{"class":162},[130,6708,6709,6711,6713,6715,6717,6719,6721,6723,6725,6727],{"class":132,"line":1232},[130,6710,6088],{"class":158},[130,6712,163],{"class":162},[130,6714,5800],{"class":180},[130,6716,235],{"class":162},[130,6718,6097],{"class":180},[130,6720,235],{"class":162},[130,6722,6102],{"class":180},[130,6724,235],{"class":162},[130,6726,6107],{"class":180},[130,6728,204],{"class":162},[130,6730,6731,6733],{"class":132,"line":1237},[130,6732,344],{"class":162},[130,6734,338],{"class":158},[130,6736,6737],{"class":132,"line":1243},[130,6738,420],{"emptyLinePlaceholder":419},[130,6740,6742],{"class":6741,"line":1256},[132,6385],[130,6743,6744],{"class":328},"    // enableMarker が true の場合マーカーを表示\n",[130,6746,6748,6750,6752,6754,6756,6759,6761],{"class":6747,"line":1268},[132,6385],[130,6749,5910],{"class":136},[130,6751,561],{"class":158},[130,6753,6205],{"class":180},[130,6755,235],{"class":162},[130,6757,6758],{"class":180},"enableMarker",[130,6760,1174],{"class":158},[130,6762,152],{"class":162},[130,6764,6766,6769,6771,6773],{"class":6765,"line":1273},[132,6385],[130,6767,6768],{"class":554},"      new",[130,6770,6608],{"class":143},[130,6772,148],{"class":158},[130,6774,152],{"class":162},[130,6776,6778,6781],{"class":6777,"line":1301},[132,6385],[130,6779,6780],{"class":180},"        map",[130,6782,204],{"class":162},[130,6784,6786,6789,6791,6793,6795,6797],{"class":6785,"line":1320},[132,6385],[130,6787,6788],{"class":158},"        position",[130,6790,163],{"class":162},[130,6792,5753],{"class":180},[130,6794,235],{"class":162},[130,6796,6059],{"class":180},[130,6798,204],{"class":162},[130,6800,6802,6804],{"class":6801,"line":1325},[132,6385],[130,6803,335],{"class":162},[130,6805,338],{"class":158},[130,6807,6809],{"class":6808,"line":1344},[132,6385],[130,6810,2105],{"class":162},[130,6812,6813,6815],{"class":132,"line":1349},[130,6814,1981],{"class":162},[130,6816,338],{"class":158},[130,6818,6819,6821],{"class":132,"line":1354},[130,6820,358],{"class":162},[130,6822,338],{"class":180},[130,6824,6825,6827,6829],{"class":132,"line":1359},[130,6826,2193],{"class":162},[130,6828,5698],{"class":2149},[130,6830,2170],{"class":162},[130,6832,6833],{"class":132,"line":1365},[130,6834,420],{"emptyLinePlaceholder":419},[130,6836,6837,6839,6841],{"class":132,"line":1379},[130,6838,608],{"class":162},[130,6840,2130],{"class":2149},[130,6842,2170],{"class":162},[130,6844,6845,6847],{"class":132,"line":1391},[130,6846,2989],{"class":162},[130,6848,6154],{"class":2149},[130,6850,6851,6853,6855,6857,6859],{"class":132,"line":1396},[130,6852,6159],{"class":2153},[130,6854,2160],{"class":162},[130,6856,2163],{"class":193},[130,6858,5917],{"class":197},[130,6860,2789],{"class":193},[130,6862,6863,6865,6867,6869,6871],{"class":132,"line":1419},[130,6864,6172],{"class":2153},[130,6866,2160],{"class":162},[130,6868,2163],{"class":193},[130,6870,6179],{"class":197},[130,6872,2789],{"class":193},[130,6874,6875,6877],{"class":132,"line":1425},[130,6876,6187],{"class":6186},[130,6878,2170],{"class":162},[130,6880,6881,6883,6885],{"class":132,"line":1445},[130,6882,2193],{"class":162},[130,6884,2130],{"class":2149},[130,6886,2170],{"class":162},[76,6888,6200],{"id":6889},"コンポーネントを呼ぶ側-1",[83,6891,6893],{"className":2137,"code":6892,"filename":6210,"language":2140,"meta":92,"style":92},"\u003CBasicMap\n  :position=\"{ lat: 35.685355, lng: 139.753144 }\"\n  :enable-marker=\"true\"\n  :zoom=\"14\"\n/>\n",[90,6894,6895,6902,6932,6948,6962],{"__ignoreMap":92},[130,6896,6897,6899],{"class":132,"line":133},[130,6898,608],{"class":162},[130,6900,6901],{"class":2149},"BasicMap\n",[130,6903,6904,6906,6908,6910,6912,6914,6916,6918,6920,6922,6924,6926,6928,6930],{"class":132,"line":155},[130,6905,4815],{"class":162},[130,6907,6059],{"class":2153},[130,6909,2160],{"class":162},[130,6911,2163],{"class":4823},[130,6913,2341],{"class":162},[130,6915,5726],{"class":158},[130,6917,163],{"class":162},[130,6919,6240],{"class":2349},[130,6921,325],{"class":162},[130,6923,5736],{"class":158},[130,6925,163],{"class":162},[130,6927,6249],{"class":2349},[130,6929,505],{"class":162},[130,6931,2789],{"class":4823},[130,6933,6934,6936,6939,6941,6943,6946],{"class":132,"line":169},[130,6935,4815],{"class":162},[130,6937,6938],{"class":2153},"enable-marker",[130,6940,2160],{"class":162},[130,6942,2163],{"class":4823},[130,6944,6945],{"class":1450},"true",[130,6947,2789],{"class":4823},[130,6949,6950,6952,6954,6956,6958,6960],{"class":132,"line":185},[130,6951,4815],{"class":162},[130,6953,6075],{"class":2153},[130,6955,2160],{"class":162},[130,6957,2163],{"class":4823},[130,6959,6264],{"class":2349},[130,6961,2789],{"class":4823},[130,6963,6964],{"class":132,"line":207},[130,6965,4756],{"class":180},[76,6967,6272],{"id":6968},"画面表示はこんな感じ-1",[6274,6970],{":position":6276,":zoom":6264,":enable-marker":6945},[11,6972,6974],{"id":6973},"_2点間のルート表示","2点間のルート表示",[16,6976,6977],{},"今度は、2点間のルートを表示してみます。",[76,6979,6980],{"id":6980},"コンポーネント作成",[16,6982,6983,6984,6987],{},"ルート表示用に新たに",[90,6985,6986],{},"~/components/map/RouteMap.vue","を作成します。",[83,6989,6991],{"className":2137,"code":6990,"filename":6986,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\ntype Position = { lat: number, lng: number }\n\nconst props = defineProps\u003C{\n  positions: {\n    start: Position\n    end: Position\n  }\n}>()\n\nconst config = useRuntimeConfig()\n\nconst mapRef = ref\u003CHTMLElement | null>(null)\n\nconst { onLoaded } = useScriptGoogleMaps()\n\nonMounted(() => {\n  onLoaded(async (instance) => {\n    if (!mapRef.value) {\n      return\n    }\n\n    const maps = await instance.maps\n    const { Map } = await maps.importLibrary('maps') as google.maps.MapsLibrary\n    // routes ライブラリから DirectionsService（経路検索）と DirectionsRenderer（経路描画）を取得\n    const { DirectionsService, DirectionsRenderer } = await maps.importLibrary('routes') as google.maps.RoutesLibrary\n\n    // 地図インスタンスを作成\n    const map = new Map(mapRef.value, {\n      mapId: config.public.googleMaps.mapId,\n    })\n\n    // インスタンス生成\n    const directionsService = new DirectionsService()\n    const directionsRenderer = new DirectionsRenderer()\n\n    // 地図上にルートを描画する設定\n    directionsRenderer.setMap(map)\n\n    // 出発地と目的地の緯度経度を LatLng オブジェクトに変換\n    const origin = new google.maps.LatLng(props.positions.start.lat, props.positions.start.lng)\n    const destination = new google.maps.LatLng(props.positions.end.lat, props.positions.end.lng)\n\n    // 経路検索のリクエストを作成\n    const request = {\n      origin,\n      destination,\n      travelMode: google.maps.TravelMode.DRIVING,\n    }\n\n    // 経路を検索して描画する\n    directionsService.route(request, (result, status) => {\n      // ステータスが OK（正常）ならルートを地図上に描画\n      if (status === 'OK') {\n        directionsRenderer.setDirections(result)\n      }\n    })\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv\n    ref=\"mapRef\"\n    class=\"w-full aspect-video\"\n  />\n\u003C/template>\n",[90,6992,6993,7013,7039,7043,7055,7064,7073,7082,7086,7092,7096,7108,7112,7138,7142,7158,7162,7174,7192,7210,7214,7218,7222,7238,7280,7285,7335,7339,7344,7368,7390,7396,7400,7405,7420,7435,7439,7444,7461,7465,7470,7530,7586,7590,7595,7606,7613,7620,7645,7649,7653,7658,7691,7696,7719,7735,7740,7746,7752,7758,7766,7770,7778,7784,7796,7808,7814],{"__ignoreMap":92},[130,6994,6995,6997,6999,7001,7003,7005,7007,7009,7011],{"class":132,"line":133},[130,6996,608],{"class":162},[130,6998,5698],{"class":2149},[130,7000,2154],{"class":2153},[130,7002,2157],{"class":2153},[130,7004,2160],{"class":162},[130,7006,2163],{"class":193},[130,7008,126],{"class":197},[130,7010,2163],{"class":193},[130,7012,2170],{"class":162},[130,7014,7015,7017,7019,7021,7023,7025,7027,7029,7031,7033,7035,7037],{"class":132,"line":155},[130,7016,3726],{"class":546},[130,7018,5719],{"class":570},[130,7020,555],{"class":554},[130,7022,499],{"class":162},[130,7024,5726],{"class":1925},[130,7026,163],{"class":554},[130,7028,5731],{"class":580},[130,7030,325],{"class":162},[130,7032,5736],{"class":1925},[130,7034,163],{"class":554},[130,7036,5731],{"class":580},[130,7038,1998],{"class":162},[130,7040,7041],{"class":132,"line":169},[130,7042,420],{"emptyLinePlaceholder":419},[130,7044,7045,7047,7049,7051,7053],{"class":132,"line":185},[130,7046,1012],{"class":546},[130,7048,5753],{"class":597},[130,7050,555],{"class":554},[130,7052,5758],{"class":143},[130,7054,5761],{"class":162},[130,7056,7057,7060,7062],{"class":132,"line":207},[130,7058,7059],{"class":1925},"  positions",[130,7061,163],{"class":554},[130,7063,166],{"class":162},[130,7065,7066,7069,7071],{"class":132,"line":224},[130,7067,7068],{"class":1925},"    start",[130,7070,163],{"class":554},[130,7072,5771],{"class":570},[130,7074,7075,7078,7080],{"class":132,"line":245},[130,7076,7077],{"class":1925},"    end",[130,7079,163],{"class":554},[130,7081,5771],{"class":570},[130,7083,7084],{"class":132,"line":265},[130,7085,352],{"class":162},[130,7087,7088,7090],{"class":132,"line":283},[130,7089,5787],{"class":162},[130,7091,669],{"class":180},[130,7093,7094],{"class":132,"line":302},[130,7095,420],{"emptyLinePlaceholder":419},[130,7097,7098,7100,7102,7104,7106],{"class":132,"line":332},[130,7099,1012],{"class":546},[130,7101,5800],{"class":597},[130,7103,555],{"class":554},[130,7105,5805],{"class":143},[130,7107,669],{"class":180},[130,7109,7110],{"class":132,"line":341},[130,7111,420],{"emptyLinePlaceholder":419},[130,7113,7114,7116,7118,7120,7122,7124,7126,7128,7130,7132,7134,7136],{"class":132,"line":349},[130,7115,1012],{"class":546},[130,7117,5818],{"class":597},[130,7119,555],{"class":554},[130,7121,5823],{"class":143},[130,7123,608],{"class":162},[130,7125,5828],{"class":570},[130,7127,2061],{"class":554},[130,7129,1171],{"class":580},[130,7131,618],{"class":162},[130,7133,148],{"class":180},[130,7135,5839],{"class":1170},[130,7137,338],{"class":180},[130,7139,7140],{"class":132,"line":355},[130,7141,420],{"emptyLinePlaceholder":419},[130,7143,7144,7146,7148,7150,7152,7154,7156],{"class":132,"line":783},[130,7145,1012],{"class":546},[130,7147,499],{"class":162},[130,7149,5854],{"class":597},[130,7151,505],{"class":162},[130,7153,555],{"class":554},[130,7155,5861],{"class":143},[130,7157,669],{"class":180},[130,7159,7160],{"class":132,"line":793},[130,7161,420],{"emptyLinePlaceholder":419},[130,7163,7164,7166,7168,7170,7172],{"class":132,"line":798},[130,7165,5872],{"class":143},[130,7167,148],{"class":180},[130,7169,260],{"class":162},[130,7171,587],{"class":546},[130,7173,166],{"class":162},[130,7175,7176,7178,7180,7182,7184,7186,7188,7190],{"class":132,"line":806},[130,7177,5890],{"class":143},[130,7179,148],{"class":158},[130,7181,1622],{"class":546},[130,7183,561],{"class":162},[130,7185,5899],{"class":564},[130,7187,584],{"class":162},[130,7189,587],{"class":546},[130,7191,166],{"class":162},[130,7193,7194,7196,7198,7200,7202,7204,7206,7208],{"class":132,"line":1073},[130,7195,5910],{"class":136},[130,7197,561],{"class":158},[130,7199,1432],{"class":554},[130,7201,5917],{"class":180},[130,7203,235],{"class":162},[130,7205,5922],{"class":180},[130,7207,1174],{"class":158},[130,7209,152],{"class":162},[130,7211,7212],{"class":132,"line":1086},[130,7213,5931],{"class":136},[130,7215,7216],{"class":132,"line":1092},[130,7217,2105],{"class":162},[130,7219,7220],{"class":132,"line":1128},[130,7221,420],{"emptyLinePlaceholder":419},[130,7223,7224,7226,7228,7230,7232,7234,7236],{"class":132,"line":1151},[130,7225,5949],{"class":546},[130,7227,5952],{"class":597},[130,7229,555],{"class":554},[130,7231,603],{"class":136},[130,7233,5959],{"class":180},[130,7235,235],{"class":162},[130,7237,5964],{"class":180},[130,7239,7240,7242,7244,7246,7248,7250,7252,7254,7256,7258,7260,7262,7264,7266,7268,7270,7272,7274,7276,7278],{"class":132,"line":1156},[130,7241,5949],{"class":546},[130,7243,499],{"class":162},[130,7245,5978],{"class":597},[130,7247,505],{"class":162},[130,7249,555],{"class":554},[130,7251,603],{"class":136},[130,7253,5952],{"class":180},[130,7255,235],{"class":162},[130,7257,5991],{"class":143},[130,7259,148],{"class":158},[130,7261,201],{"class":193},[130,7263,5998],{"class":197},[130,7265,201],{"class":193},[130,7267,1174],{"class":158},[130,7269,6005],{"class":136},[130,7271,6008],{"class":570},[130,7273,235],{"class":162},[130,7275,5998],{"class":570},[130,7277,235],{"class":162},[130,7279,6017],{"class":570},[130,7281,7282],{"class":132,"line":1179},[130,7283,7284],{"class":328},"    // routes ライブラリから DirectionsService（経路検索）と DirectionsRenderer（経路描画）を取得\n",[130,7286,7287,7289,7291,7294,7296,7299,7301,7303,7305,7307,7309,7311,7313,7315,7318,7320,7322,7324,7326,7328,7330,7332],{"class":132,"line":1188},[130,7288,5949],{"class":546},[130,7290,499],{"class":162},[130,7292,7293],{"class":597}," DirectionsService",[130,7295,325],{"class":162},[130,7297,7298],{"class":597}," DirectionsRenderer",[130,7300,505],{"class":162},[130,7302,555],{"class":554},[130,7304,603],{"class":136},[130,7306,5952],{"class":180},[130,7308,235],{"class":162},[130,7310,5991],{"class":143},[130,7312,148],{"class":158},[130,7314,201],{"class":193},[130,7316,7317],{"class":197},"routes",[130,7319,201],{"class":193},[130,7321,1174],{"class":158},[130,7323,6005],{"class":136},[130,7325,6008],{"class":570},[130,7327,235],{"class":162},[130,7329,5998],{"class":570},[130,7331,235],{"class":162},[130,7333,7334],{"class":570},"RoutesLibrary\n",[130,7336,7337],{"class":132,"line":1193},[130,7338,420],{"emptyLinePlaceholder":419},[130,7340,7341],{"class":132,"line":1198},[130,7342,7343],{"class":328},"    // 地図インスタンスを作成\n",[130,7345,7346,7348,7350,7352,7354,7356,7358,7360,7362,7364,7366],{"class":132,"line":1222},[130,7347,5949],{"class":546},[130,7349,6655],{"class":597},[130,7351,555],{"class":554},[130,7353,6660],{"class":554},[130,7355,5978],{"class":143},[130,7357,148],{"class":158},[130,7359,5917],{"class":180},[130,7361,235],{"class":162},[130,7363,5922],{"class":180},[130,7365,325],{"class":162},[130,7367,166],{"class":162},[130,7369,7370,7372,7374,7376,7378,7380,7382,7384,7386,7388],{"class":132,"line":1227},[130,7371,6088],{"class":158},[130,7373,163],{"class":162},[130,7375,5800],{"class":180},[130,7377,235],{"class":162},[130,7379,6097],{"class":180},[130,7381,235],{"class":162},[130,7383,6102],{"class":180},[130,7385,235],{"class":162},[130,7387,6107],{"class":180},[130,7389,204],{"class":162},[130,7391,7392,7394],{"class":132,"line":1232},[130,7393,344],{"class":162},[130,7395,338],{"class":158},[130,7397,7398],{"class":132,"line":1237},[130,7399,420],{"emptyLinePlaceholder":419},[130,7401,7402],{"class":132,"line":1243},[130,7403,7404],{"class":328},"    // インスタンス生成\n",[130,7406,7407,7409,7412,7414,7416,7418],{"class":132,"line":1256},[130,7408,5949],{"class":546},[130,7410,7411],{"class":597}," directionsService",[130,7413,555],{"class":554},[130,7415,6660],{"class":554},[130,7417,7293],{"class":143},[130,7419,669],{"class":158},[130,7421,7422,7424,7427,7429,7431,7433],{"class":132,"line":1268},[130,7423,5949],{"class":546},[130,7425,7426],{"class":597}," directionsRenderer",[130,7428,555],{"class":554},[130,7430,6660],{"class":554},[130,7432,7298],{"class":143},[130,7434,669],{"class":158},[130,7436,7437],{"class":132,"line":1273},[130,7438,420],{"emptyLinePlaceholder":419},[130,7440,7441],{"class":132,"line":1301},[130,7442,7443],{"class":328},"    // 地図上にルートを描画する設定\n",[130,7445,7446,7449,7451,7454,7456,7459],{"class":132,"line":1320},[130,7447,7448],{"class":180},"    directionsRenderer",[130,7450,235],{"class":162},[130,7452,7453],{"class":143},"setMap",[130,7455,148],{"class":158},[130,7457,7458],{"class":180},"map",[130,7460,338],{"class":158},[130,7462,7463],{"class":132,"line":1325},[130,7464,420],{"emptyLinePlaceholder":419},[130,7466,7467],{"class":132,"line":1344},[130,7468,7469],{"class":328},"    // 出発地と目的地の緯度経度を LatLng オブジェクトに変換\n",[130,7471,7472,7474,7477,7479,7481,7483,7485,7487,7489,7492,7494,7496,7498,7501,7503,7506,7508,7511,7513,7515,7517,7519,7521,7523,7525,7528],{"class":132,"line":1349},[130,7473,5949],{"class":546},[130,7475,7476],{"class":597}," origin",[130,7478,555],{"class":554},[130,7480,6660],{"class":554},[130,7482,6008],{"class":180},[130,7484,235],{"class":162},[130,7486,5998],{"class":180},[130,7488,235],{"class":162},[130,7490,7491],{"class":143},"LatLng",[130,7493,148],{"class":158},[130,7495,6205],{"class":180},[130,7497,235],{"class":162},[130,7499,7500],{"class":180},"positions",[130,7502,235],{"class":162},[130,7504,7505],{"class":180},"start",[130,7507,235],{"class":162},[130,7509,7510],{"class":180},"lat",[130,7512,325],{"class":162},[130,7514,5753],{"class":180},[130,7516,235],{"class":162},[130,7518,7500],{"class":180},[130,7520,235],{"class":162},[130,7522,7505],{"class":180},[130,7524,235],{"class":162},[130,7526,7527],{"class":180},"lng",[130,7529,338],{"class":158},[130,7531,7532,7534,7537,7539,7541,7543,7545,7547,7549,7551,7553,7555,7557,7559,7561,7564,7566,7568,7570,7572,7574,7576,7578,7580,7582,7584],{"class":132,"line":1354},[130,7533,5949],{"class":546},[130,7535,7536],{"class":597}," destination",[130,7538,555],{"class":554},[130,7540,6660],{"class":554},[130,7542,6008],{"class":180},[130,7544,235],{"class":162},[130,7546,5998],{"class":180},[130,7548,235],{"class":162},[130,7550,7491],{"class":143},[130,7552,148],{"class":158},[130,7554,6205],{"class":180},[130,7556,235],{"class":162},[130,7558,7500],{"class":180},[130,7560,235],{"class":162},[130,7562,7563],{"class":180},"end",[130,7565,235],{"class":162},[130,7567,7510],{"class":180},[130,7569,325],{"class":162},[130,7571,5753],{"class":180},[130,7573,235],{"class":162},[130,7575,7500],{"class":180},[130,7577,235],{"class":162},[130,7579,7563],{"class":180},[130,7581,235],{"class":162},[130,7583,7527],{"class":180},[130,7585,338],{"class":158},[130,7587,7588],{"class":132,"line":1359},[130,7589,420],{"emptyLinePlaceholder":419},[130,7591,7592],{"class":132,"line":1365},[130,7593,7594],{"class":328},"    // 経路検索のリクエストを作成\n",[130,7596,7597,7599,7602,7604],{"class":132,"line":1379},[130,7598,5949],{"class":546},[130,7600,7601],{"class":597}," request",[130,7603,555],{"class":554},[130,7605,166],{"class":162},[130,7607,7608,7611],{"class":132,"line":1391},[130,7609,7610],{"class":180},"      origin",[130,7612,204],{"class":162},[130,7614,7615,7618],{"class":132,"line":1396},[130,7616,7617],{"class":180},"      destination",[130,7619,204],{"class":162},[130,7621,7622,7625,7627,7629,7631,7633,7635,7638,7640,7643],{"class":132,"line":1419},[130,7623,7624],{"class":158},"      travelMode",[130,7626,163],{"class":162},[130,7628,6008],{"class":180},[130,7630,235],{"class":162},[130,7632,5998],{"class":180},[130,7634,235],{"class":162},[130,7636,7637],{"class":180},"TravelMode",[130,7639,235],{"class":162},[130,7641,7642],{"class":597},"DRIVING",[130,7644,204],{"class":162},[130,7646,7647],{"class":132,"line":1425},[130,7648,2105],{"class":162},[130,7650,7651],{"class":132,"line":1445},[130,7652,420],{"emptyLinePlaceholder":419},[130,7654,7655],{"class":132,"line":1454},[130,7656,7657],{"class":328},"    // 経路を検索して描画する\n",[130,7659,7660,7663,7665,7668,7670,7673,7675,7677,7680,7682,7685,7687,7689],{"class":132,"line":1459},[130,7661,7662],{"class":180},"    directionsService",[130,7664,235],{"class":162},[130,7666,7667],{"class":143},"route",[130,7669,148],{"class":158},[130,7671,7672],{"class":180},"request",[130,7674,325],{"class":162},[130,7676,561],{"class":162},[130,7678,7679],{"class":564},"result",[130,7681,325],{"class":162},[130,7683,7684],{"class":564}," status",[130,7686,584],{"class":162},[130,7688,587],{"class":546},[130,7690,166],{"class":162},[130,7692,7693],{"class":132,"line":1464},[130,7694,7695],{"class":328},"      // ステータスが OK（正常）ならルートを地図上に描画\n",[130,7697,7698,7701,7703,7706,7708,7710,7713,7715,7717],{"class":132,"line":1491},[130,7699,7700],{"class":136},"      if",[130,7702,561],{"class":158},[130,7704,7705],{"class":180},"status",[130,7707,1167],{"class":554},[130,7709,194],{"class":193},[130,7711,7712],{"class":197},"OK",[130,7714,201],{"class":193},[130,7716,1174],{"class":158},[130,7718,152],{"class":162},[130,7720,7721,7724,7726,7729,7731,7733],{"class":132,"line":1510},[130,7722,7723],{"class":180},"        directionsRenderer",[130,7725,235],{"class":162},[130,7727,7728],{"class":143},"setDirections",[130,7730,148],{"class":158},[130,7732,7679],{"class":180},[130,7734,338],{"class":158},[130,7736,7737],{"class":132,"line":1522},[130,7738,7739],{"class":162},"      }\n",[130,7741,7742,7744],{"class":132,"line":1530},[130,7743,344],{"class":162},[130,7745,338],{"class":158},[130,7747,7748,7750],{"class":132,"line":1536},[130,7749,1981],{"class":162},[130,7751,338],{"class":158},[130,7753,7754,7756],{"class":132,"line":1541},[130,7755,358],{"class":162},[130,7757,338],{"class":180},[130,7759,7760,7762,7764],{"class":132,"line":1547},[130,7761,2193],{"class":162},[130,7763,5698],{"class":2149},[130,7765,2170],{"class":162},[130,7767,7768],{"class":132,"line":1565},[130,7769,420],{"emptyLinePlaceholder":419},[130,7771,7772,7774,7776],{"class":132,"line":4432},[130,7773,608],{"class":162},[130,7775,2130],{"class":2149},[130,7777,2170],{"class":162},[130,7779,7780,7782],{"class":132,"line":4438},[130,7781,2989],{"class":162},[130,7783,6154],{"class":2149},[130,7785,7786,7788,7790,7792,7794],{"class":132,"line":4446},[130,7787,6159],{"class":2153},[130,7789,2160],{"class":162},[130,7791,2163],{"class":193},[130,7793,5917],{"class":197},[130,7795,2789],{"class":193},[130,7797,7798,7800,7802,7804,7806],{"class":132,"line":4459},[130,7799,6172],{"class":2153},[130,7801,2160],{"class":162},[130,7803,2163],{"class":193},[130,7805,6179],{"class":197},[130,7807,2789],{"class":193},[130,7809,7810,7812],{"class":132,"line":4474},[130,7811,6187],{"class":6186},[130,7813,2170],{"class":162},[130,7815,7816,7818,7820],{"class":132,"line":4489},[130,7817,2193],{"class":162},[130,7819,2130],{"class":2149},[130,7821,2170],{"class":162},[76,7823,6200],{"id":7824},"コンポーネントを呼ぶ側-2",[83,7826,7828],{"className":2137,"code":7827,"language":2140,"meta":92,"style":92},"// 皇居 ~ 都庁 間のルート表示\n\u003CRouteMap\n  :positions=\"{\n    start: { lat: 35.685355, lng: 139.753144 },\n    end: { lat: 35.689419, lng: 139.691682 },\n  }\"\n/>\n",[90,7829,7830,7835,7842,7854,7879,7905,7911],{"__ignoreMap":92},[130,7831,7832],{"class":132,"line":133},[130,7833,7834],{"class":180},"// 皇居 ~ 都庁 間のルート表示\n",[130,7836,7837,7839],{"class":132,"line":155},[130,7838,608],{"class":162},[130,7840,7841],{"class":2149},"RouteMap\n",[130,7843,7844,7846,7848,7850,7852],{"class":132,"line":169},[130,7845,4815],{"class":162},[130,7847,7500],{"class":2153},[130,7849,2160],{"class":162},[130,7851,2163],{"class":4823},[130,7853,152],{"class":162},[130,7855,7856,7858,7860,7862,7864,7866,7868,7870,7872,7874,7876],{"class":132,"line":185},[130,7857,7068],{"class":158},[130,7859,163],{"class":162},[130,7861,499],{"class":162},[130,7863,5726],{"class":158},[130,7865,163],{"class":162},[130,7867,6240],{"class":2349},[130,7869,325],{"class":162},[130,7871,5736],{"class":158},[130,7873,163],{"class":162},[130,7875,6249],{"class":2349},[130,7877,7878],{"class":162}," },\n",[130,7880,7881,7883,7885,7887,7889,7891,7894,7896,7898,7900,7903],{"class":132,"line":207},[130,7882,7077],{"class":158},[130,7884,163],{"class":162},[130,7886,499],{"class":162},[130,7888,5726],{"class":158},[130,7890,163],{"class":162},[130,7892,7893],{"class":2349}," 35.689419",[130,7895,325],{"class":162},[130,7897,5736],{"class":158},[130,7899,163],{"class":162},[130,7901,7902],{"class":2349}," 139.691682",[130,7904,7878],{"class":162},[130,7906,7907,7909],{"class":132,"line":224},[130,7908,1981],{"class":162},[130,7910,2789],{"class":4823},[130,7912,7913],{"class":132,"line":245},[130,7914,4756],{"class":180},[76,7916,6272],{"id":7917},"画面表示はこんな感じ-2",[7919,7920],"route-map",{":positions":7921},"{\"start\":{\"lat\":35.685355,\"lng\":139.753144},\"end\":{\"lat\":35.689419,\"lng\":139.691682}}",[11,7923,7924],{"id":7924},"複数地点を経由するルート検索",[16,7926,7927],{},"2点間だと、環状のルートを表示するときに詰みます。\n例えば、山手線の一周のルートを開始・終了位置を新宿駅で設定したとします。",[16,7929,7930],{},"するとこんな感じになります↓",[7919,7932],{":positions":7933},"{\"start\":{\"lat\":35.689393,\"lng\":139.700647},\"end\":{\"lat\":35.689393,\"lng\":139.700647}}",[16,7935,7936],{},[7937,7938,7939],"em",{},"開始・終了位置が同じなので当たり前なのだが",[16,7941,7942],{},"中間ウェイポイントを設定することによってこの問題を回避します。",[76,7944,7946,6292],{"id":7945},"routemap-コンポーネント修正",[90,7947,7948],{},"RouteMap",[16,7950,7951,7952,6297],{},"中間ウェイポイントを配列で受け取れるように ",[90,7953,6205],{},[83,7955,7959],{"className":2137,"code":7956,"filename":7957,"highlights":7958,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\ntype Position = { lat: number, lng: number }\n\nconst props = defineProps\u003C{\n  positions: {\n    start: Position\n    end: Position\n    // 中間ウェイポイントを配列で受け取る\n    waypoints?: Position[]\n  }\n  enableMarker?: boolean\n}>()\n\nconst config = useRuntimeConfig()\n\nconst mapRef = ref\u003CHTMLElement | null>(null)\n\nconst { onLoaded } = useScriptGoogleMaps({\n  apiKey: config.public.scripts.googleMaps.apiKey,\n})\n\nonMounted(() => {\n  onLoaded(async (instance) => {\n    if (!mapRef.value) {\n      return\n    }\n\n    const maps = await instance.maps\n    const { Map } = await maps.importLibrary('maps') as google.maps.MapsLibrary\n    const { DirectionsService, DirectionsRenderer } = await maps.importLibrary('routes') as google.maps.RoutesLibrary\n    const map = new Map(mapRef.value, {\n      mapId: config.public.googleMaps.mapId,\n    })\n\n    const directionsService = new DirectionsService()\n    const directionsRenderer = new DirectionsRenderer({ suppressMarkers: props.enableMarker })\n    directionsRenderer.setMap(map)\n\n    const origin = new google.maps.LatLng(props.positions.start.lat, props.positions.start.lng)\n    const destination = new google.maps.LatLng(props.positions.end.lat, props.positions.end.lng)\n\n    const request = {\n      origin,\n      destination,\n      // 中間ウェイポイントが存在する場合は LatLng に変換、なければ空配列\n      waypoints: props.positions.waypoints\n        ? props.positions.waypoints.map(point => ({\n            location: new google.maps.LatLng(point.lat, point.lng),\n            stopover: true,\n          }))\n        : [],\n      travelMode: google.maps.TravelMode.DRIVING,\n    }\n\n    directionsService.route(request, (result, status) => {\n      if (status === 'OK') {\n        directionsRenderer.setDirections(result)\n      }\n    })\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv\n    ref=\"mapRef\"\n    class=\"w-full aspect-video\"\n  />\n\u003C/template>\n\n","RouteMap.vue",[265,283,1379,1391,1396,1419,1425,1445,1454],[90,7960,7961,7981,8007,8011,8023,8031,8039,8047,8053,8066,8070,8078,8084,8088,8100,8104,8130,8134,8152,8181,8187,8191,8203,8221,8239,8243,8247,8251,8267,8309,8355,8379,8401,8407,8411,8425,8456,8470,8474,8528,8582,8586,8596,8602,8608,8614,8633,8665,8706,8719,8728,8738,8760,8764,8768,8796,8816,8830,8834,8840,8846,8852,8860,8864,8872,8878,8890,8902,8908],{"__ignoreMap":92},[130,7962,7963,7965,7967,7969,7971,7973,7975,7977,7979],{"class":132,"line":133},[130,7964,608],{"class":162},[130,7966,5698],{"class":2149},[130,7968,2154],{"class":2153},[130,7970,2157],{"class":2153},[130,7972,2160],{"class":162},[130,7974,2163],{"class":193},[130,7976,126],{"class":197},[130,7978,2163],{"class":193},[130,7980,2170],{"class":162},[130,7982,7983,7985,7987,7989,7991,7993,7995,7997,7999,8001,8003,8005],{"class":132,"line":155},[130,7984,3726],{"class":546},[130,7986,5719],{"class":570},[130,7988,555],{"class":554},[130,7990,499],{"class":162},[130,7992,5726],{"class":1925},[130,7994,163],{"class":554},[130,7996,5731],{"class":580},[130,7998,325],{"class":162},[130,8000,5736],{"class":1925},[130,8002,163],{"class":554},[130,8004,5731],{"class":580},[130,8006,1998],{"class":162},[130,8008,8009],{"class":132,"line":169},[130,8010,420],{"emptyLinePlaceholder":419},[130,8012,8013,8015,8017,8019,8021],{"class":132,"line":185},[130,8014,1012],{"class":546},[130,8016,5753],{"class":597},[130,8018,555],{"class":554},[130,8020,5758],{"class":143},[130,8022,5761],{"class":162},[130,8024,8025,8027,8029],{"class":132,"line":207},[130,8026,7059],{"class":1925},[130,8028,163],{"class":554},[130,8030,166],{"class":162},[130,8032,8033,8035,8037],{"class":132,"line":224},[130,8034,7068],{"class":1925},[130,8036,163],{"class":554},[130,8038,5771],{"class":570},[130,8040,8041,8043,8045],{"class":132,"line":245},[130,8042,7077],{"class":1925},[130,8044,163],{"class":554},[130,8046,5771],{"class":570},[130,8048,8050],{"class":8049,"line":265},[132,6385],[130,8051,8052],{"class":328},"    // 中間ウェイポイントを配列で受け取る\n",[130,8054,8056,8059,8061,8063],{"class":8055,"line":283},[132,6385],[130,8057,8058],{"class":1925},"    waypoints",[130,8060,5779],{"class":554},[130,8062,5719],{"class":570},[130,8064,8065],{"class":180},"[]\n",[130,8067,8068],{"class":132,"line":302},[130,8069,352],{"class":162},[130,8071,8072,8074,8076],{"class":132,"line":332},[130,8073,6394],{"class":1925},[130,8075,5779],{"class":554},[130,8077,1388],{"class":580},[130,8079,8080,8082],{"class":132,"line":341},[130,8081,5787],{"class":162},[130,8083,669],{"class":180},[130,8085,8086],{"class":132,"line":349},[130,8087,420],{"emptyLinePlaceholder":419},[130,8089,8090,8092,8094,8096,8098],{"class":132,"line":355},[130,8091,1012],{"class":546},[130,8093,5800],{"class":597},[130,8095,555],{"class":554},[130,8097,5805],{"class":143},[130,8099,669],{"class":180},[130,8101,8102],{"class":132,"line":783},[130,8103,420],{"emptyLinePlaceholder":419},[130,8105,8106,8108,8110,8112,8114,8116,8118,8120,8122,8124,8126,8128],{"class":132,"line":793},[130,8107,1012],{"class":546},[130,8109,5818],{"class":597},[130,8111,555],{"class":554},[130,8113,5823],{"class":143},[130,8115,608],{"class":162},[130,8117,5828],{"class":570},[130,8119,2061],{"class":554},[130,8121,1171],{"class":580},[130,8123,618],{"class":162},[130,8125,148],{"class":180},[130,8127,5839],{"class":1170},[130,8129,338],{"class":180},[130,8131,8132],{"class":132,"line":798},[130,8133,420],{"emptyLinePlaceholder":419},[130,8135,8136,8138,8140,8142,8144,8146,8148,8150],{"class":132,"line":806},[130,8137,1012],{"class":546},[130,8139,499],{"class":162},[130,8141,5854],{"class":597},[130,8143,505],{"class":162},[130,8145,555],{"class":554},[130,8147,5861],{"class":143},[130,8149,148],{"class":180},[130,8151,152],{"class":162},[130,8153,8154,8157,8159,8161,8163,8165,8167,8170,8172,8174,8176,8179],{"class":132,"line":1073},[130,8155,8156],{"class":158},"  apiKey",[130,8158,163],{"class":162},[130,8160,5800],{"class":180},[130,8162,235],{"class":162},[130,8164,6097],{"class":180},[130,8166,235],{"class":162},[130,8168,8169],{"class":180},"scripts",[130,8171,235],{"class":162},[130,8173,6102],{"class":180},[130,8175,235],{"class":162},[130,8177,8178],{"class":180},"apiKey",[130,8180,204],{"class":162},[130,8182,8183,8185],{"class":132,"line":1086},[130,8184,358],{"class":162},[130,8186,338],{"class":180},[130,8188,8189],{"class":132,"line":1092},[130,8190,420],{"emptyLinePlaceholder":419},[130,8192,8193,8195,8197,8199,8201],{"class":132,"line":1128},[130,8194,5872],{"class":143},[130,8196,148],{"class":180},[130,8198,260],{"class":162},[130,8200,587],{"class":546},[130,8202,166],{"class":162},[130,8204,8205,8207,8209,8211,8213,8215,8217,8219],{"class":132,"line":1151},[130,8206,5890],{"class":143},[130,8208,148],{"class":158},[130,8210,1622],{"class":546},[130,8212,561],{"class":162},[130,8214,5899],{"class":564},[130,8216,584],{"class":162},[130,8218,587],{"class":546},[130,8220,166],{"class":162},[130,8222,8223,8225,8227,8229,8231,8233,8235,8237],{"class":132,"line":1156},[130,8224,5910],{"class":136},[130,8226,561],{"class":158},[130,8228,1432],{"class":554},[130,8230,5917],{"class":180},[130,8232,235],{"class":162},[130,8234,5922],{"class":180},[130,8236,1174],{"class":158},[130,8238,152],{"class":162},[130,8240,8241],{"class":132,"line":1179},[130,8242,5931],{"class":136},[130,8244,8245],{"class":132,"line":1188},[130,8246,2105],{"class":162},[130,8248,8249],{"class":132,"line":1193},[130,8250,420],{"emptyLinePlaceholder":419},[130,8252,8253,8255,8257,8259,8261,8263,8265],{"class":132,"line":1198},[130,8254,5949],{"class":546},[130,8256,5952],{"class":597},[130,8258,555],{"class":554},[130,8260,603],{"class":136},[130,8262,5959],{"class":180},[130,8264,235],{"class":162},[130,8266,5964],{"class":180},[130,8268,8269,8271,8273,8275,8277,8279,8281,8283,8285,8287,8289,8291,8293,8295,8297,8299,8301,8303,8305,8307],{"class":132,"line":1222},[130,8270,5949],{"class":546},[130,8272,499],{"class":162},[130,8274,5978],{"class":597},[130,8276,505],{"class":162},[130,8278,555],{"class":554},[130,8280,603],{"class":136},[130,8282,5952],{"class":180},[130,8284,235],{"class":162},[130,8286,5991],{"class":143},[130,8288,148],{"class":158},[130,8290,201],{"class":193},[130,8292,5998],{"class":197},[130,8294,201],{"class":193},[130,8296,1174],{"class":158},[130,8298,6005],{"class":136},[130,8300,6008],{"class":570},[130,8302,235],{"class":162},[130,8304,5998],{"class":570},[130,8306,235],{"class":162},[130,8308,6017],{"class":570},[130,8310,8311,8313,8315,8317,8319,8321,8323,8325,8327,8329,8331,8333,8335,8337,8339,8341,8343,8345,8347,8349,8351,8353],{"class":132,"line":1227},[130,8312,5949],{"class":546},[130,8314,499],{"class":162},[130,8316,7293],{"class":597},[130,8318,325],{"class":162},[130,8320,7298],{"class":597},[130,8322,505],{"class":162},[130,8324,555],{"class":554},[130,8326,603],{"class":136},[130,8328,5952],{"class":180},[130,8330,235],{"class":162},[130,8332,5991],{"class":143},[130,8334,148],{"class":158},[130,8336,201],{"class":193},[130,8338,7317],{"class":197},[130,8340,201],{"class":193},[130,8342,1174],{"class":158},[130,8344,6005],{"class":136},[130,8346,6008],{"class":570},[130,8348,235],{"class":162},[130,8350,5998],{"class":570},[130,8352,235],{"class":162},[130,8354,7334],{"class":570},[130,8356,8357,8359,8361,8363,8365,8367,8369,8371,8373,8375,8377],{"class":132,"line":1232},[130,8358,5949],{"class":546},[130,8360,6655],{"class":597},[130,8362,555],{"class":554},[130,8364,6660],{"class":554},[130,8366,5978],{"class":143},[130,8368,148],{"class":158},[130,8370,5917],{"class":180},[130,8372,235],{"class":162},[130,8374,5922],{"class":180},[130,8376,325],{"class":162},[130,8378,166],{"class":162},[130,8380,8381,8383,8385,8387,8389,8391,8393,8395,8397,8399],{"class":132,"line":1237},[130,8382,6088],{"class":158},[130,8384,163],{"class":162},[130,8386,5800],{"class":180},[130,8388,235],{"class":162},[130,8390,6097],{"class":180},[130,8392,235],{"class":162},[130,8394,6102],{"class":180},[130,8396,235],{"class":162},[130,8398,6107],{"class":180},[130,8400,204],{"class":162},[130,8402,8403,8405],{"class":132,"line":1243},[130,8404,344],{"class":162},[130,8406,338],{"class":158},[130,8408,8409],{"class":132,"line":1256},[130,8410,420],{"emptyLinePlaceholder":419},[130,8412,8413,8415,8417,8419,8421,8423],{"class":132,"line":1268},[130,8414,5949],{"class":546},[130,8416,7411],{"class":597},[130,8418,555],{"class":554},[130,8420,6660],{"class":554},[130,8422,7293],{"class":143},[130,8424,669],{"class":158},[130,8426,8427,8429,8431,8433,8435,8437,8439,8441,8444,8446,8448,8450,8452,8454],{"class":132,"line":1273},[130,8428,5949],{"class":546},[130,8430,7426],{"class":597},[130,8432,555],{"class":554},[130,8434,6660],{"class":554},[130,8436,7298],{"class":143},[130,8438,148],{"class":158},[130,8440,2341],{"class":162},[130,8442,8443],{"class":158}," suppressMarkers",[130,8445,163],{"class":162},[130,8447,5753],{"class":180},[130,8449,235],{"class":162},[130,8451,6758],{"class":180},[130,8453,505],{"class":162},[130,8455,338],{"class":158},[130,8457,8458,8460,8462,8464,8466,8468],{"class":132,"line":1301},[130,8459,7448],{"class":180},[130,8461,235],{"class":162},[130,8463,7453],{"class":143},[130,8465,148],{"class":158},[130,8467,7458],{"class":180},[130,8469,338],{"class":158},[130,8471,8472],{"class":132,"line":1320},[130,8473,420],{"emptyLinePlaceholder":419},[130,8475,8476,8478,8480,8482,8484,8486,8488,8490,8492,8494,8496,8498,8500,8502,8504,8506,8508,8510,8512,8514,8516,8518,8520,8522,8524,8526],{"class":132,"line":1325},[130,8477,5949],{"class":546},[130,8479,7476],{"class":597},[130,8481,555],{"class":554},[130,8483,6660],{"class":554},[130,8485,6008],{"class":180},[130,8487,235],{"class":162},[130,8489,5998],{"class":180},[130,8491,235],{"class":162},[130,8493,7491],{"class":143},[130,8495,148],{"class":158},[130,8497,6205],{"class":180},[130,8499,235],{"class":162},[130,8501,7500],{"class":180},[130,8503,235],{"class":162},[130,8505,7505],{"class":180},[130,8507,235],{"class":162},[130,8509,7510],{"class":180},[130,8511,325],{"class":162},[130,8513,5753],{"class":180},[130,8515,235],{"class":162},[130,8517,7500],{"class":180},[130,8519,235],{"class":162},[130,8521,7505],{"class":180},[130,8523,235],{"class":162},[130,8525,7527],{"class":180},[130,8527,338],{"class":158},[130,8529,8530,8532,8534,8536,8538,8540,8542,8544,8546,8548,8550,8552,8554,8556,8558,8560,8562,8564,8566,8568,8570,8572,8574,8576,8578,8580],{"class":132,"line":1344},[130,8531,5949],{"class":546},[130,8533,7536],{"class":597},[130,8535,555],{"class":554},[130,8537,6660],{"class":554},[130,8539,6008],{"class":180},[130,8541,235],{"class":162},[130,8543,5998],{"class":180},[130,8545,235],{"class":162},[130,8547,7491],{"class":143},[130,8549,148],{"class":158},[130,8551,6205],{"class":180},[130,8553,235],{"class":162},[130,8555,7500],{"class":180},[130,8557,235],{"class":162},[130,8559,7563],{"class":180},[130,8561,235],{"class":162},[130,8563,7510],{"class":180},[130,8565,325],{"class":162},[130,8567,5753],{"class":180},[130,8569,235],{"class":162},[130,8571,7500],{"class":180},[130,8573,235],{"class":162},[130,8575,7563],{"class":180},[130,8577,235],{"class":162},[130,8579,7527],{"class":180},[130,8581,338],{"class":158},[130,8583,8584],{"class":132,"line":1349},[130,8585,420],{"emptyLinePlaceholder":419},[130,8587,8588,8590,8592,8594],{"class":132,"line":1354},[130,8589,5949],{"class":546},[130,8591,7601],{"class":597},[130,8593,555],{"class":554},[130,8595,166],{"class":162},[130,8597,8598,8600],{"class":132,"line":1359},[130,8599,7610],{"class":180},[130,8601,204],{"class":162},[130,8603,8604,8606],{"class":132,"line":1365},[130,8605,7617],{"class":180},[130,8607,204],{"class":162},[130,8609,8611],{"class":8610,"line":1379},[132,6385],[130,8612,8613],{"class":328},"      // 中間ウェイポイントが存在する場合は LatLng に変換、なければ空配列\n",[130,8615,8617,8620,8622,8624,8626,8628,8630],{"class":8616,"line":1391},[132,6385],[130,8618,8619],{"class":158},"      waypoints",[130,8621,163],{"class":162},[130,8623,5753],{"class":180},[130,8625,235],{"class":162},[130,8627,7500],{"class":180},[130,8629,235],{"class":162},[130,8631,8632],{"class":180},"waypoints\n",[130,8634,8636,8639,8641,8643,8645,8647,8650,8652,8654,8656,8659,8661,8663],{"class":8635,"line":1396},[132,6385],[130,8637,8638],{"class":554},"        ?",[130,8640,5753],{"class":180},[130,8642,235],{"class":162},[130,8644,7500],{"class":180},[130,8646,235],{"class":162},[130,8648,8649],{"class":180},"waypoints",[130,8651,235],{"class":162},[130,8653,7458],{"class":143},[130,8655,148],{"class":158},[130,8657,8658],{"class":564},"point",[130,8660,587],{"class":546},[130,8662,561],{"class":158},[130,8664,152],{"class":162},[130,8666,8668,8671,8673,8675,8677,8679,8681,8683,8685,8687,8689,8691,8693,8695,8698,8700,8702,8704],{"class":8667,"line":1419},[132,6385],[130,8669,8670],{"class":158},"            location",[130,8672,163],{"class":162},[130,8674,6660],{"class":554},[130,8676,6008],{"class":180},[130,8678,235],{"class":162},[130,8680,5998],{"class":180},[130,8682,235],{"class":162},[130,8684,7491],{"class":143},[130,8686,148],{"class":158},[130,8688,8658],{"class":180},[130,8690,235],{"class":162},[130,8692,7510],{"class":180},[130,8694,325],{"class":162},[130,8696,8697],{"class":180}," point",[130,8699,235],{"class":162},[130,8701,7527],{"class":180},[130,8703,584],{"class":158},[130,8705,204],{"class":162},[130,8707,8709,8712,8714,8717],{"class":8708,"line":1425},[132,6385],[130,8710,8711],{"class":158},"            stopover",[130,8713,163],{"class":162},[130,8715,8716],{"class":1450}," true",[130,8718,204],{"class":162},[130,8720,8722,8725],{"class":8721,"line":1445},[132,6385],[130,8723,8724],{"class":162},"          }",[130,8726,8727],{"class":158},"))\n",[130,8729,8731,8734,8736],{"class":8730,"line":1454},[132,6385],[130,8732,8733],{"class":554},"        :",[130,8735,1974],{"class":158},[130,8737,204],{"class":162},[130,8739,8740,8742,8744,8746,8748,8750,8752,8754,8756,8758],{"class":132,"line":1459},[130,8741,7624],{"class":158},[130,8743,163],{"class":162},[130,8745,6008],{"class":180},[130,8747,235],{"class":162},[130,8749,5998],{"class":180},[130,8751,235],{"class":162},[130,8753,7637],{"class":180},[130,8755,235],{"class":162},[130,8757,7642],{"class":597},[130,8759,204],{"class":162},[130,8761,8762],{"class":132,"line":1464},[130,8763,2105],{"class":162},[130,8765,8766],{"class":132,"line":1491},[130,8767,420],{"emptyLinePlaceholder":419},[130,8769,8770,8772,8774,8776,8778,8780,8782,8784,8786,8788,8790,8792,8794],{"class":132,"line":1510},[130,8771,7662],{"class":180},[130,8773,235],{"class":162},[130,8775,7667],{"class":143},[130,8777,148],{"class":158},[130,8779,7672],{"class":180},[130,8781,325],{"class":162},[130,8783,561],{"class":162},[130,8785,7679],{"class":564},[130,8787,325],{"class":162},[130,8789,7684],{"class":564},[130,8791,584],{"class":162},[130,8793,587],{"class":546},[130,8795,166],{"class":162},[130,8797,8798,8800,8802,8804,8806,8808,8810,8812,8814],{"class":132,"line":1522},[130,8799,7700],{"class":136},[130,8801,561],{"class":158},[130,8803,7705],{"class":180},[130,8805,1167],{"class":554},[130,8807,194],{"class":193},[130,8809,7712],{"class":197},[130,8811,201],{"class":193},[130,8813,1174],{"class":158},[130,8815,152],{"class":162},[130,8817,8818,8820,8822,8824,8826,8828],{"class":132,"line":1530},[130,8819,7723],{"class":180},[130,8821,235],{"class":162},[130,8823,7728],{"class":143},[130,8825,148],{"class":158},[130,8827,7679],{"class":180},[130,8829,338],{"class":158},[130,8831,8832],{"class":132,"line":1536},[130,8833,7739],{"class":162},[130,8835,8836,8838],{"class":132,"line":1541},[130,8837,344],{"class":162},[130,8839,338],{"class":158},[130,8841,8842,8844],{"class":132,"line":1547},[130,8843,1981],{"class":162},[130,8845,338],{"class":158},[130,8847,8848,8850],{"class":132,"line":1565},[130,8849,358],{"class":162},[130,8851,338],{"class":180},[130,8853,8854,8856,8858],{"class":132,"line":4432},[130,8855,2193],{"class":162},[130,8857,5698],{"class":2149},[130,8859,2170],{"class":162},[130,8861,8862],{"class":132,"line":4438},[130,8863,420],{"emptyLinePlaceholder":419},[130,8865,8866,8868,8870],{"class":132,"line":4446},[130,8867,608],{"class":162},[130,8869,2130],{"class":2149},[130,8871,2170],{"class":162},[130,8873,8874,8876],{"class":132,"line":4459},[130,8875,2989],{"class":162},[130,8877,6154],{"class":2149},[130,8879,8880,8882,8884,8886,8888],{"class":132,"line":4474},[130,8881,6159],{"class":2153},[130,8883,2160],{"class":162},[130,8885,2163],{"class":193},[130,8887,5917],{"class":197},[130,8889,2789],{"class":193},[130,8891,8892,8894,8896,8898,8900],{"class":132,"line":4489},[130,8893,6172],{"class":2153},[130,8895,2160],{"class":162},[130,8897,2163],{"class":193},[130,8899,6179],{"class":197},[130,8901,2789],{"class":193},[130,8903,8904,8906],{"class":132,"line":4504},[130,8905,6187],{"class":6186},[130,8907,2170],{"class":162},[130,8909,8910,8912,8914],{"class":132,"line":4518},[130,8911,2193],{"class":162},[130,8913,2130],{"class":2149},[130,8915,2170],{"class":162},[76,8917,6200],{"id":8918},"コンポーネントを呼ぶ側-3",[83,8920,8922],{"className":2137,"code":8921,"filename":6210,"language":2140,"meta":92,"style":92},"\u003CRouteMap\n  :positions=\"{\n    start: { lat: 35.690921, lng: 139.70025799999996 },\n    end: { lat: 35.690921, lng: 139.70025799999996 },\n    waypoints: [\n      { lat: 35.683061, lng: 139.702042 }, // 代々木\n      { lat: 35.670168, lng: 139.70268699999997 }, // 原宿\n      { lat: 35.658517, lng: 139.70133399999997 }, // 渋谷\n      { lat: 35.64669, lng: 139.710106 }, // 恵比寿\n      { lat: 35.633998, lng: 139.715828 }, // 目黒\n      { lat: 35.626446, lng: 139.72344399999997 }, // 五反田\n      { lat: 35.6197, lng: 139.72855300000003 }, // 大崎\n      { lat: 35.630152, lng: 139.74044000000004 }, // 品川\n      { lat: 35.645736, lng: 139.74757499999998 }, // 田町\n      { lat: 35.655646, lng: 139.756749 }, // 浜松町\n      { lat: 35.665498, lng: 139.75964 }, // 新橋\n      { lat: 35.675069, lng: 139.763328 }, // 有楽町\n      { lat: 35.681382, lng: 139.76608399999998 }, // 東京\n      { lat: 35.69169, lng: 139.77088300000003 }, // 神田\n      { lat: 35.698683, lng: 139.77421900000002 }, // 秋葉原\n      { lat: 35.707438, lng: 139.774632 }, // 御徒町\n      { lat: 35.713768, lng: 139.77725399999997 }, // 上野\n      { lat: 35.727772, lng: 139.770987 }, // 日暮里\n      { lat: 35.738062, lng: 139.76085999999998 }, // 田端\n      { lat: 35.733492, lng: 139.73934499999996 }, // 巣鴨\n      { lat: 35.731401, lng: 139.72866199999999 }, // 大崎\n      { lat: 35.728926, lng: 139.71038 }, // 池袋\n      { lat: 35.721204, lng: 139.706587 }, // 目白\n      { lat: 35.712285, lng: 139.70378200000005 }, // 高田馬場\n      { lat: 35.701306, lng: 139.706587 }, // 新大久保\n    ],\n  }\"\n/>\n",[90,8923,8924,8930,8942,8968,8992,9001,9028,9053,9078,9103,9128,9153,9178,9203,9228,9253,9278,9303,9328,9353,9378,9403,9428,9453,9478,9503,9527,9552,9577,9602,9626,9633,9639],{"__ignoreMap":92},[130,8925,8926,8928],{"class":132,"line":133},[130,8927,608],{"class":162},[130,8929,7841],{"class":2149},[130,8931,8932,8934,8936,8938,8940],{"class":132,"line":155},[130,8933,4815],{"class":162},[130,8935,7500],{"class":2153},[130,8937,2160],{"class":162},[130,8939,2163],{"class":4823},[130,8941,152],{"class":162},[130,8943,8944,8946,8948,8950,8952,8954,8957,8959,8961,8963,8966],{"class":132,"line":169},[130,8945,7068],{"class":158},[130,8947,163],{"class":162},[130,8949,499],{"class":162},[130,8951,5726],{"class":158},[130,8953,163],{"class":162},[130,8955,8956],{"class":2349}," 35.690921",[130,8958,325],{"class":162},[130,8960,5736],{"class":158},[130,8962,163],{"class":162},[130,8964,8965],{"class":2349}," 139.70025799999996",[130,8967,7878],{"class":162},[130,8969,8970,8972,8974,8976,8978,8980,8982,8984,8986,8988,8990],{"class":132,"line":185},[130,8971,7077],{"class":158},[130,8973,163],{"class":162},[130,8975,499],{"class":162},[130,8977,5726],{"class":158},[130,8979,163],{"class":162},[130,8981,8956],{"class":2349},[130,8983,325],{"class":162},[130,8985,5736],{"class":158},[130,8987,163],{"class":162},[130,8989,8965],{"class":2349},[130,8991,7878],{"class":162},[130,8993,8994,8996,8998],{"class":132,"line":207},[130,8995,8058],{"class":158},[130,8997,163],{"class":162},[130,8999,9000],{"class":180}," [\n",[130,9002,9003,9006,9008,9010,9013,9015,9017,9019,9022,9025],{"class":132,"line":224},[130,9004,9005],{"class":162},"      {",[130,9007,5726],{"class":158},[130,9009,163],{"class":162},[130,9011,9012],{"class":2349}," 35.683061",[130,9014,325],{"class":162},[130,9016,5736],{"class":158},[130,9018,163],{"class":162},[130,9020,9021],{"class":2349}," 139.702042",[130,9023,9024],{"class":162}," },",[130,9026,9027],{"class":328}," // 代々木\n",[130,9029,9030,9032,9034,9036,9039,9041,9043,9045,9048,9050],{"class":132,"line":245},[130,9031,9005],{"class":162},[130,9033,5726],{"class":158},[130,9035,163],{"class":162},[130,9037,9038],{"class":2349}," 35.670168",[130,9040,325],{"class":162},[130,9042,5736],{"class":158},[130,9044,163],{"class":162},[130,9046,9047],{"class":2349}," 139.70268699999997",[130,9049,9024],{"class":162},[130,9051,9052],{"class":328}," // 原宿\n",[130,9054,9055,9057,9059,9061,9064,9066,9068,9070,9073,9075],{"class":132,"line":265},[130,9056,9005],{"class":162},[130,9058,5726],{"class":158},[130,9060,163],{"class":162},[130,9062,9063],{"class":2349}," 35.658517",[130,9065,325],{"class":162},[130,9067,5736],{"class":158},[130,9069,163],{"class":162},[130,9071,9072],{"class":2349}," 139.70133399999997",[130,9074,9024],{"class":162},[130,9076,9077],{"class":328}," // 渋谷\n",[130,9079,9080,9082,9084,9086,9089,9091,9093,9095,9098,9100],{"class":132,"line":283},[130,9081,9005],{"class":162},[130,9083,5726],{"class":158},[130,9085,163],{"class":162},[130,9087,9088],{"class":2349}," 35.64669",[130,9090,325],{"class":162},[130,9092,5736],{"class":158},[130,9094,163],{"class":162},[130,9096,9097],{"class":2349}," 139.710106",[130,9099,9024],{"class":162},[130,9101,9102],{"class":328}," // 恵比寿\n",[130,9104,9105,9107,9109,9111,9114,9116,9118,9120,9123,9125],{"class":132,"line":302},[130,9106,9005],{"class":162},[130,9108,5726],{"class":158},[130,9110,163],{"class":162},[130,9112,9113],{"class":2349}," 35.633998",[130,9115,325],{"class":162},[130,9117,5736],{"class":158},[130,9119,163],{"class":162},[130,9121,9122],{"class":2349}," 139.715828",[130,9124,9024],{"class":162},[130,9126,9127],{"class":328}," // 目黒\n",[130,9129,9130,9132,9134,9136,9139,9141,9143,9145,9148,9150],{"class":132,"line":332},[130,9131,9005],{"class":162},[130,9133,5726],{"class":158},[130,9135,163],{"class":162},[130,9137,9138],{"class":2349}," 35.626446",[130,9140,325],{"class":162},[130,9142,5736],{"class":158},[130,9144,163],{"class":162},[130,9146,9147],{"class":2349}," 139.72344399999997",[130,9149,9024],{"class":162},[130,9151,9152],{"class":328}," // 五反田\n",[130,9154,9155,9157,9159,9161,9164,9166,9168,9170,9173,9175],{"class":132,"line":341},[130,9156,9005],{"class":162},[130,9158,5726],{"class":158},[130,9160,163],{"class":162},[130,9162,9163],{"class":2349}," 35.6197",[130,9165,325],{"class":162},[130,9167,5736],{"class":158},[130,9169,163],{"class":162},[130,9171,9172],{"class":2349}," 139.72855300000003",[130,9174,9024],{"class":162},[130,9176,9177],{"class":328}," // 大崎\n",[130,9179,9180,9182,9184,9186,9189,9191,9193,9195,9198,9200],{"class":132,"line":349},[130,9181,9005],{"class":162},[130,9183,5726],{"class":158},[130,9185,163],{"class":162},[130,9187,9188],{"class":2349}," 35.630152",[130,9190,325],{"class":162},[130,9192,5736],{"class":158},[130,9194,163],{"class":162},[130,9196,9197],{"class":2349}," 139.74044000000004",[130,9199,9024],{"class":162},[130,9201,9202],{"class":328}," // 品川\n",[130,9204,9205,9207,9209,9211,9214,9216,9218,9220,9223,9225],{"class":132,"line":355},[130,9206,9005],{"class":162},[130,9208,5726],{"class":158},[130,9210,163],{"class":162},[130,9212,9213],{"class":2349}," 35.645736",[130,9215,325],{"class":162},[130,9217,5736],{"class":158},[130,9219,163],{"class":162},[130,9221,9222],{"class":2349}," 139.74757499999998",[130,9224,9024],{"class":162},[130,9226,9227],{"class":328}," // 田町\n",[130,9229,9230,9232,9234,9236,9239,9241,9243,9245,9248,9250],{"class":132,"line":783},[130,9231,9005],{"class":162},[130,9233,5726],{"class":158},[130,9235,163],{"class":162},[130,9237,9238],{"class":2349}," 35.655646",[130,9240,325],{"class":162},[130,9242,5736],{"class":158},[130,9244,163],{"class":162},[130,9246,9247],{"class":2349}," 139.756749",[130,9249,9024],{"class":162},[130,9251,9252],{"class":328}," // 浜松町\n",[130,9254,9255,9257,9259,9261,9264,9266,9268,9270,9273,9275],{"class":132,"line":793},[130,9256,9005],{"class":162},[130,9258,5726],{"class":158},[130,9260,163],{"class":162},[130,9262,9263],{"class":2349}," 35.665498",[130,9265,325],{"class":162},[130,9267,5736],{"class":158},[130,9269,163],{"class":162},[130,9271,9272],{"class":2349}," 139.75964",[130,9274,9024],{"class":162},[130,9276,9277],{"class":328}," // 新橋\n",[130,9279,9280,9282,9284,9286,9289,9291,9293,9295,9298,9300],{"class":132,"line":798},[130,9281,9005],{"class":162},[130,9283,5726],{"class":158},[130,9285,163],{"class":162},[130,9287,9288],{"class":2349}," 35.675069",[130,9290,325],{"class":162},[130,9292,5736],{"class":158},[130,9294,163],{"class":162},[130,9296,9297],{"class":2349}," 139.763328",[130,9299,9024],{"class":162},[130,9301,9302],{"class":328}," // 有楽町\n",[130,9304,9305,9307,9309,9311,9314,9316,9318,9320,9323,9325],{"class":132,"line":806},[130,9306,9005],{"class":162},[130,9308,5726],{"class":158},[130,9310,163],{"class":162},[130,9312,9313],{"class":2349}," 35.681382",[130,9315,325],{"class":162},[130,9317,5736],{"class":158},[130,9319,163],{"class":162},[130,9321,9322],{"class":2349}," 139.76608399999998",[130,9324,9024],{"class":162},[130,9326,9327],{"class":328}," // 東京\n",[130,9329,9330,9332,9334,9336,9339,9341,9343,9345,9348,9350],{"class":132,"line":1073},[130,9331,9005],{"class":162},[130,9333,5726],{"class":158},[130,9335,163],{"class":162},[130,9337,9338],{"class":2349}," 35.69169",[130,9340,325],{"class":162},[130,9342,5736],{"class":158},[130,9344,163],{"class":162},[130,9346,9347],{"class":2349}," 139.77088300000003",[130,9349,9024],{"class":162},[130,9351,9352],{"class":328}," // 神田\n",[130,9354,9355,9357,9359,9361,9364,9366,9368,9370,9373,9375],{"class":132,"line":1086},[130,9356,9005],{"class":162},[130,9358,5726],{"class":158},[130,9360,163],{"class":162},[130,9362,9363],{"class":2349}," 35.698683",[130,9365,325],{"class":162},[130,9367,5736],{"class":158},[130,9369,163],{"class":162},[130,9371,9372],{"class":2349}," 139.77421900000002",[130,9374,9024],{"class":162},[130,9376,9377],{"class":328}," // 秋葉原\n",[130,9379,9380,9382,9384,9386,9389,9391,9393,9395,9398,9400],{"class":132,"line":1092},[130,9381,9005],{"class":162},[130,9383,5726],{"class":158},[130,9385,163],{"class":162},[130,9387,9388],{"class":2349}," 35.707438",[130,9390,325],{"class":162},[130,9392,5736],{"class":158},[130,9394,163],{"class":162},[130,9396,9397],{"class":2349}," 139.774632",[130,9399,9024],{"class":162},[130,9401,9402],{"class":328}," // 御徒町\n",[130,9404,9405,9407,9409,9411,9414,9416,9418,9420,9423,9425],{"class":132,"line":1128},[130,9406,9005],{"class":162},[130,9408,5726],{"class":158},[130,9410,163],{"class":162},[130,9412,9413],{"class":2349}," 35.713768",[130,9415,325],{"class":162},[130,9417,5736],{"class":158},[130,9419,163],{"class":162},[130,9421,9422],{"class":2349}," 139.77725399999997",[130,9424,9024],{"class":162},[130,9426,9427],{"class":328}," // 上野\n",[130,9429,9430,9432,9434,9436,9439,9441,9443,9445,9448,9450],{"class":132,"line":1151},[130,9431,9005],{"class":162},[130,9433,5726],{"class":158},[130,9435,163],{"class":162},[130,9437,9438],{"class":2349}," 35.727772",[130,9440,325],{"class":162},[130,9442,5736],{"class":158},[130,9444,163],{"class":162},[130,9446,9447],{"class":2349}," 139.770987",[130,9449,9024],{"class":162},[130,9451,9452],{"class":328}," // 日暮里\n",[130,9454,9455,9457,9459,9461,9464,9466,9468,9470,9473,9475],{"class":132,"line":1156},[130,9456,9005],{"class":162},[130,9458,5726],{"class":158},[130,9460,163],{"class":162},[130,9462,9463],{"class":2349}," 35.738062",[130,9465,325],{"class":162},[130,9467,5736],{"class":158},[130,9469,163],{"class":162},[130,9471,9472],{"class":2349}," 139.76085999999998",[130,9474,9024],{"class":162},[130,9476,9477],{"class":328}," // 田端\n",[130,9479,9480,9482,9484,9486,9489,9491,9493,9495,9498,9500],{"class":132,"line":1179},[130,9481,9005],{"class":162},[130,9483,5726],{"class":158},[130,9485,163],{"class":162},[130,9487,9488],{"class":2349}," 35.733492",[130,9490,325],{"class":162},[130,9492,5736],{"class":158},[130,9494,163],{"class":162},[130,9496,9497],{"class":2349}," 139.73934499999996",[130,9499,9024],{"class":162},[130,9501,9502],{"class":328}," // 巣鴨\n",[130,9504,9505,9507,9509,9511,9514,9516,9518,9520,9523,9525],{"class":132,"line":1188},[130,9506,9005],{"class":162},[130,9508,5726],{"class":158},[130,9510,163],{"class":162},[130,9512,9513],{"class":2349}," 35.731401",[130,9515,325],{"class":162},[130,9517,5736],{"class":158},[130,9519,163],{"class":162},[130,9521,9522],{"class":2349}," 139.72866199999999",[130,9524,9024],{"class":162},[130,9526,9177],{"class":328},[130,9528,9529,9531,9533,9535,9538,9540,9542,9544,9547,9549],{"class":132,"line":1193},[130,9530,9005],{"class":162},[130,9532,5726],{"class":158},[130,9534,163],{"class":162},[130,9536,9537],{"class":2349}," 35.728926",[130,9539,325],{"class":162},[130,9541,5736],{"class":158},[130,9543,163],{"class":162},[130,9545,9546],{"class":2349}," 139.71038",[130,9548,9024],{"class":162},[130,9550,9551],{"class":328}," // 池袋\n",[130,9553,9554,9556,9558,9560,9563,9565,9567,9569,9572,9574],{"class":132,"line":1198},[130,9555,9005],{"class":162},[130,9557,5726],{"class":158},[130,9559,163],{"class":162},[130,9561,9562],{"class":2349}," 35.721204",[130,9564,325],{"class":162},[130,9566,5736],{"class":158},[130,9568,163],{"class":162},[130,9570,9571],{"class":2349}," 139.706587",[130,9573,9024],{"class":162},[130,9575,9576],{"class":328}," // 目白\n",[130,9578,9579,9581,9583,9585,9588,9590,9592,9594,9597,9599],{"class":132,"line":1222},[130,9580,9005],{"class":162},[130,9582,5726],{"class":158},[130,9584,163],{"class":162},[130,9586,9587],{"class":2349}," 35.712285",[130,9589,325],{"class":162},[130,9591,5736],{"class":158},[130,9593,163],{"class":162},[130,9595,9596],{"class":2349}," 139.70378200000005",[130,9598,9024],{"class":162},[130,9600,9601],{"class":328}," // 高田馬場\n",[130,9603,9604,9606,9608,9610,9613,9615,9617,9619,9621,9623],{"class":132,"line":1227},[130,9605,9005],{"class":162},[130,9607,5726],{"class":158},[130,9609,163],{"class":162},[130,9611,9612],{"class":2349}," 35.701306",[130,9614,325],{"class":162},[130,9616,5736],{"class":158},[130,9618,163],{"class":162},[130,9620,9571],{"class":2349},[130,9622,9024],{"class":162},[130,9624,9625],{"class":328}," // 新大久保\n",[130,9627,9628,9631],{"class":132,"line":1232},[130,9629,9630],{"class":180},"    ]",[130,9632,204],{"class":162},[130,9634,9635,9637],{"class":132,"line":1237},[130,9636,1981],{"class":162},[130,9638,2789],{"class":4823},[130,9640,9641],{"class":132,"line":1243},[130,9642,4756],{"class":180},[76,9644,6272],{"id":9645},"画面表示はこんな感じ-3",[9647,9648],"route-map-sample",{},[2476,9650,9651],{},[16,9652,9653,9655,9656,9658],{},[90,9654,5178],{}," 出発地点、到着地点、中間地点あわせて25箇所までしか設定できません。",[35,9657],{},[7937,9659,9660],{},"(山手線は30駅あるので影の薄い駅を端折りました。)",[11,9662,9663],{"id":9663},"おわりに",[16,9665,9666,9668,9669,9671],{},[90,9667,5236],{},"を使ってマップの表示などをまとめました。",[35,9670],{},"\n今回紹介した API 以外にもおもしろそうな API がいくつもあるのでまた試してみたいです。",[11,9673,5095],{"id":5095},[2523,9675],{"url":9676},"https://qiita.com/butchi_y/items/3a6b70b38e13dc56ef13",[2420,9678,9679],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sipQf, html code.shiki .sipQf{--shiki-light:#90A4AE;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sfFde, html code.shiki .sfFde{--shiki-light:#39ADB5;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sywW5, html code.shiki .sywW5{--shiki-light:#E2931D;--shiki-default:#FFB757;--shiki-dark:#B392F0}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .s-3tI, html code.shiki .s-3tI{--shiki-light:#E53935;--shiki-default:#FFB757;--shiki-dark:#FFAB70}html pre.shiki code .snYqn, html code.shiki .snYqn{--shiki-light:#E2931D;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .s4Pz2, html code.shiki .s4Pz2{--shiki-light:#39ADB5;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sFHE5, html code.shiki .sFHE5{--shiki-light:#F76D47;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sDdkT, html code.shiki .sDdkT{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#FFB1AF;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}html pre.shiki code .s5sbo, html code.shiki .s5sbo{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#9ECBFF}html pre.shiki code .sBxIE, html code.shiki .sBxIE{--shiki-light:#FF5370;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .spR0o, html code.shiki .spR0o{--shiki-light:#91B859;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .s08Pv, html code.shiki .s08Pv{--shiki-light:#39ADB5;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sBpHv, html code.shiki .sBpHv{--shiki-light:#91B859;--shiki-default:#72F088;--shiki-dark:#85E89D}",{"title":92,"searchDepth":169,"depth":169,"links":9681},[9682,9683,9691,9697,9703,9708,9714,9715],{"id":2464,"depth":155,"text":2464},{"id":5182,"depth":155,"text":5182,"children":9684},[9685,9686,9687],{"id":5185,"depth":169,"text":5186},{"id":5227,"depth":169,"text":5228},{"id":5364,"depth":169,"text":5365,"children":9688},[9689,9690],{"id":5382,"depth":185,"text":5382},{"id":5562,"depth":185,"text":5565},{"id":5667,"depth":155,"text":5667,"children":9692},[9693,9695,9696],{"id":5673,"depth":169,"text":9694},"BasicMap コンポーネント作成",{"id":6200,"depth":169,"text":6200},{"id":6272,"depth":169,"text":6272},{"id":6279,"depth":155,"text":6279,"children":9698},[9699,9701,9702],{"id":6288,"depth":169,"text":9700},"BasicMap.vue コンポーネント修正",{"id":6889,"depth":169,"text":6200},{"id":6968,"depth":169,"text":6272},{"id":6973,"depth":155,"text":6974,"children":9704},[9705,9706,9707],{"id":6980,"depth":169,"text":6980},{"id":7824,"depth":169,"text":6200},{"id":7917,"depth":169,"text":6272},{"id":7924,"depth":155,"text":7924,"children":9709},[9710,9712,9713],{"id":7945,"depth":169,"text":9711},"RouteMap コンポーネント修正",{"id":8918,"depth":169,"text":6200},{"id":9645,"depth":169,"text":6272},{"id":9663,"depth":155,"text":9663},{"id":5095,"depth":155,"text":5095},"2025-07-22T00:00:00.000Z","Nuxt + Google Maps API を使ってマップの表示とルート表示を行います。",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1753114202/tsukiyama-blog/google-maps-api/google-maps-api_camiip.png","/tech/google-maps-api",{"title":5153,"description":9717},"tech/google-maps-api",[2452,9724,5414],"GCP","cZV7XxoesdZSvVSxUybykNkYAIu78-Y3OXKXK4R2r7A",{"id":9727,"title":9728,"body":9729,"date":10577,"description":10578,"extension":381,"icon":2444,"meta":10579,"navigation":419,"ogImage":10580,"path":10581,"published":419,"publishedAt":2455,"seo":10582,"stem":10583,"tags":10584,"updatedAt":2455,"__hash__":10585},"tech/tech/nuxt-basic-auth.md","Nuxt で Basic 認証を実装してみる",{"type":8,"value":9730,"toc":10565},[9731,9733,9736,9739,9749,9752,9758,9761,9765,10361,10363,10477,10483,10486,10489,10498,10508,10511,10515,10524,10527,10546,10549,10551,10562],[11,9732,2464],{"id":2464},[16,9734,9735],{},"Nuxt での Basic 認証を実装する方法について気になったので実装してみたときの備忘録です。",[11,9737,9738],{"id":9738},"参考",[16,9740,9741,9742,9745,9746,9748],{},"サードパーティ製のモジュールとして公開されている ",[90,9743,9744],{},"@kgierke/nuxt-basic-auth"," を参考に実装しました。",[35,9747],{},"\nこだわりがなければ、こちらをインストールして使用することをお勧めします。",[2523,9750],{"url":9751},"https://github.com/kgierke/nuxt-basic-auth/tree/main",[16,9753,9754,9755,9757],{},"公式モジュールではないことと、最終更新日が8ヶ月前だったので自分で実装してみることにしました。",[35,9756],{},"\n（全体に一律で認証をかけたいだけで、わざわざモジュール入れるほどではなかったので）",[11,9759,9760],{"id":9760},"ソースコード",[76,9762,9764],{"id":9763},"servermiddleware","server/middleware",[83,9766,9769],{"className":123,"code":9767,"filename":9768,"language":126,"meta":92,"style":92},"export default defineEventHandler((event) => {\n  const { basicAuth } = useRuntimeConfig()\n\n  // ローカルでは無視する\n  if (import.meta.dev) {\n    return\n  }\n\n  // allowedRoutes に指定されていればスキップする\n  if (basicAuth.allowedRoutes?.some((route: string) => {\n    const regex = new RegExp(route)\n\n    return regex.test(event.node.req.url || '')\n  })) {\n    return\n  }\n\n  // 認証を判定する真偽値\n  let authenticated = false\n\n  // Authorizationヘッダーから認証情報を取得する\n  const credentials = event.node.req.headers.authorization?.split(' ')[1]\n\n  if (credentials) {\n    // base64 形式から utf-8 の String へ変換する\n    const [username, password] = Buffer.from(credentials, 'base64').toString('utf-8').split(':')\n\n    // username と password が一致しているかどうか\n    authenticated = username === basicAuth.username && password === basicAuth.password\n\n    // 一致していれば認証通過\n    if (authenticated) return\n  }\n\n  // 一致していなければ Unauthorized レスポンスを返す\n  event.node.res.statusCode = 401\n  event.node.res.setHeader(\n    'WWW-Authenticate',\n    'Basic realm=\"Secure Area\", charset=\"UTF-8\"',\n  )\n  event.node.res.setHeader('Content-Type', 'text/plain; charset=utf-8')\n  event.node.res.end('Access denied')\n})\n\n","~/server/middleware/basic-auth.ts",[90,9770,9771,9791,9808,9812,9817,9839,9844,9848,9852,9857,9893,9913,9917,9954,9963,9967,9971,9975,9980,9993,9997,10002,10051,10055,10068,10073,10145,10149,10154,10186,10190,10195,10209,10213,10217,10222,10246,10265,10277,10288,10292,10328,10355],{"__ignoreMap":92},[130,9772,9773,9775,9777,9779,9781,9783,9785,9787,9789],{"class":132,"line":133},[130,9774,137],{"class":136},[130,9776,140],{"class":136},[130,9778,1617],{"class":143},[130,9780,148],{"class":147},[130,9782,148],{"class":151},[130,9784,565],{"class":564},[130,9786,584],{"class":151},[130,9788,587],{"class":546},[130,9790,166],{"class":162},[130,9792,9793,9795,9797,9800,9802,9804,9806],{"class":132,"line":155},[130,9794,594],{"class":546},[130,9796,499],{"class":162},[130,9798,9799],{"class":597}," basicAuth",[130,9801,505],{"class":162},[130,9803,555],{"class":554},[130,9805,5805],{"class":143},[130,9807,669],{"class":158},[130,9809,9810],{"class":132,"line":169},[130,9811,420],{"emptyLinePlaceholder":419},[130,9813,9814],{"class":132,"line":185},[130,9815,9816],{"class":328},"  // ローカルでは無視する\n",[130,9818,9819,9821,9823,9825,9827,9830,9832,9835,9837],{"class":132,"line":207},[130,9820,1159],{"class":136},[130,9822,561],{"class":158},[130,9824,493],{"class":136},[130,9826,235],{"class":162},[130,9828,9829],{"class":597},"meta",[130,9831,235],{"class":162},[130,9833,9834],{"class":180},"dev",[130,9836,1174],{"class":158},[130,9838,152],{"class":162},[130,9840,9841],{"class":132,"line":224},[130,9842,9843],{"class":136},"    return\n",[130,9845,9846],{"class":132,"line":245},[130,9847,352],{"class":162},[130,9849,9850],{"class":132,"line":265},[130,9851,420],{"emptyLinePlaceholder":419},[130,9853,9854],{"class":132,"line":283},[130,9855,9856],{"class":328},"  // allowedRoutes に指定されていればスキップする\n",[130,9858,9859,9861,9863,9866,9868,9871,9874,9877,9879,9881,9883,9885,9887,9889,9891],{"class":132,"line":302},[130,9860,1159],{"class":136},[130,9862,561],{"class":158},[130,9864,9865],{"class":180},"basicAuth",[130,9867,235],{"class":162},[130,9869,9870],{"class":180},"allowedRoutes",[130,9872,9873],{"class":162},"?.",[130,9875,9876],{"class":143},"some",[130,9878,148],{"class":158},[130,9880,148],{"class":162},[130,9882,7667],{"class":564},[130,9884,163],{"class":554},[130,9886,581],{"class":580},[130,9888,584],{"class":162},[130,9890,587],{"class":546},[130,9892,166],{"class":162},[130,9894,9895,9897,9900,9902,9904,9907,9909,9911],{"class":132,"line":332},[130,9896,5949],{"class":546},[130,9898,9899],{"class":597}," regex",[130,9901,555],{"class":554},[130,9903,6660],{"class":554},[130,9905,9906],{"class":143}," RegExp",[130,9908,148],{"class":158},[130,9910,7667],{"class":180},[130,9912,338],{"class":158},[130,9914,9915],{"class":132,"line":341},[130,9916,420],{"emptyLinePlaceholder":419},[130,9918,9919,9921,9923,9925,9928,9930,9932,9934,9937,9939,9942,9944,9947,9950,9952],{"class":132,"line":349},[130,9920,1182],{"class":136},[130,9922,9899],{"class":180},[130,9924,235],{"class":162},[130,9926,9927],{"class":143},"test",[130,9929,148],{"class":158},[130,9931,565],{"class":180},[130,9933,235],{"class":162},[130,9935,9936],{"class":180},"node",[130,9938,235],{"class":162},[130,9940,9941],{"class":180},"req",[130,9943,235],{"class":162},[130,9945,9946],{"class":180},"url",[130,9948,9949],{"class":554}," ||",[130,9951,5637],{"class":193},[130,9953,338],{"class":158},[130,9955,9956,9958,9961],{"class":132,"line":355},[130,9957,1981],{"class":162},[130,9959,9960],{"class":158},")) ",[130,9962,152],{"class":162},[130,9964,9965],{"class":132,"line":783},[130,9966,9843],{"class":136},[130,9968,9969],{"class":132,"line":793},[130,9970,352],{"class":162},[130,9972,9973],{"class":132,"line":798},[130,9974,420],{"emptyLinePlaceholder":419},[130,9976,9977],{"class":132,"line":806},[130,9978,9979],{"class":328},"  // 認証を判定する真偽値\n",[130,9981,9982,9985,9988,9990],{"class":132,"line":1073},[130,9983,9984],{"class":546},"  let",[130,9986,9987],{"class":180}," authenticated",[130,9989,555],{"class":554},[130,9991,9992],{"class":1450}," false\n",[130,9994,9995],{"class":132,"line":1086},[130,9996,420],{"emptyLinePlaceholder":419},[130,9998,9999],{"class":132,"line":1092},[130,10000,10001],{"class":328},"  // Authorizationヘッダーから認証情報を取得する\n",[130,10003,10004,10006,10009,10011,10013,10015,10017,10019,10021,10023,10026,10028,10031,10033,10036,10038,10040,10042,10045,10048],{"class":132,"line":1128},[130,10005,594],{"class":546},[130,10007,10008],{"class":597}," credentials",[130,10010,555],{"class":554},[130,10012,1054],{"class":180},[130,10014,235],{"class":162},[130,10016,9936],{"class":180},[130,10018,235],{"class":162},[130,10020,9941],{"class":180},[130,10022,235],{"class":162},[130,10024,10025],{"class":180},"headers",[130,10027,235],{"class":162},[130,10029,10030],{"class":180},"authorization",[130,10032,9873],{"class":162},[130,10034,10035],{"class":143},"split",[130,10037,148],{"class":158},[130,10039,201],{"class":193},[130,10041,194],{"class":193},[130,10043,10044],{"class":158},")[",[130,10046,10047],{"class":2349},"1",[130,10049,10050],{"class":158},"]\n",[130,10052,10053],{"class":132,"line":1151},[130,10054,420],{"emptyLinePlaceholder":419},[130,10056,10057,10059,10061,10064,10066],{"class":132,"line":1156},[130,10058,1159],{"class":136},[130,10060,561],{"class":158},[130,10062,10063],{"class":180},"credentials",[130,10065,1174],{"class":158},[130,10067,152],{"class":162},[130,10069,10070],{"class":132,"line":1179},[130,10071,10072],{"class":328},"    // base64 形式から utf-8 の String へ変換する\n",[130,10074,10075,10077,10080,10083,10085,10088,10091,10093,10096,10098,10100,10102,10104,10106,10108,10111,10113,10115,10117,10120,10122,10124,10127,10129,10131,10133,10135,10137,10139,10141,10143],{"class":132,"line":1188},[130,10076,5949],{"class":546},[130,10078,10079],{"class":162}," [",[130,10081,10082],{"class":597},"username",[130,10084,325],{"class":162},[130,10086,10087],{"class":597}," password",[130,10089,10090],{"class":162},"]",[130,10092,555],{"class":554},[130,10094,10095],{"class":180}," Buffer",[130,10097,235],{"class":162},[130,10099,886],{"class":143},[130,10101,148],{"class":158},[130,10103,10063],{"class":180},[130,10105,325],{"class":162},[130,10107,194],{"class":193},[130,10109,10110],{"class":197},"base64",[130,10112,201],{"class":193},[130,10114,584],{"class":158},[130,10116,235],{"class":162},[130,10118,10119],{"class":143},"toString",[130,10121,148],{"class":158},[130,10123,201],{"class":193},[130,10125,10126],{"class":197},"utf-8",[130,10128,201],{"class":193},[130,10130,584],{"class":158},[130,10132,235],{"class":162},[130,10134,10035],{"class":143},[130,10136,148],{"class":158},[130,10138,201],{"class":193},[130,10140,163],{"class":197},[130,10142,201],{"class":193},[130,10144,338],{"class":158},[130,10146,10147],{"class":132,"line":1193},[130,10148,420],{"emptyLinePlaceholder":419},[130,10150,10151],{"class":132,"line":1198},[130,10152,10153],{"class":328},"    // username と password が一致しているかどうか\n",[130,10155,10156,10159,10161,10164,10166,10168,10170,10172,10175,10177,10179,10181,10183],{"class":132,"line":1222},[130,10157,10158],{"class":180},"    authenticated",[130,10160,555],{"class":554},[130,10162,10163],{"class":180}," username",[130,10165,1167],{"class":554},[130,10167,9799],{"class":180},[130,10169,235],{"class":162},[130,10171,10082],{"class":180},[130,10173,10174],{"class":554}," &&",[130,10176,10087],{"class":180},[130,10178,1167],{"class":554},[130,10180,9799],{"class":180},[130,10182,235],{"class":162},[130,10184,10185],{"class":180},"password\n",[130,10187,10188],{"class":132,"line":1227},[130,10189,420],{"emptyLinePlaceholder":419},[130,10191,10192],{"class":132,"line":1232},[130,10193,10194],{"class":328},"    // 一致していれば認証通過\n",[130,10196,10197,10199,10201,10204,10206],{"class":132,"line":1237},[130,10198,5910],{"class":136},[130,10200,561],{"class":158},[130,10202,10203],{"class":180},"authenticated",[130,10205,1174],{"class":158},[130,10207,10208],{"class":136},"return\n",[130,10210,10211],{"class":132,"line":1243},[130,10212,352],{"class":162},[130,10214,10215],{"class":132,"line":1256},[130,10216,420],{"emptyLinePlaceholder":419},[130,10218,10219],{"class":132,"line":1268},[130,10220,10221],{"class":328},"  // 一致していなければ Unauthorized レスポンスを返す\n",[130,10223,10224,10227,10229,10231,10233,10236,10238,10241,10243],{"class":132,"line":1273},[130,10225,10226],{"class":180},"  event",[130,10228,235],{"class":162},[130,10230,9936],{"class":180},[130,10232,235],{"class":162},[130,10234,10235],{"class":180},"res",[130,10237,235],{"class":162},[130,10239,10240],{"class":180},"statusCode",[130,10242,555],{"class":554},[130,10244,10245],{"class":2349}," 401\n",[130,10247,10248,10250,10252,10254,10256,10258,10260,10263],{"class":132,"line":1301},[130,10249,10226],{"class":180},[130,10251,235],{"class":162},[130,10253,9936],{"class":180},[130,10255,235],{"class":162},[130,10257,10235],{"class":180},[130,10259,235],{"class":162},[130,10261,10262],{"class":143},"setHeader",[130,10264,1507],{"class":158},[130,10266,10267,10270,10273,10275],{"class":132,"line":1320},[130,10268,10269],{"class":193},"    '",[130,10271,10272],{"class":197},"WWW-Authenticate",[130,10274,201],{"class":193},[130,10276,204],{"class":162},[130,10278,10279,10281,10284,10286],{"class":132,"line":1325},[130,10280,10269],{"class":193},[130,10282,10283],{"class":197},"Basic realm=\"Secure Area\", charset=\"UTF-8\"",[130,10285,201],{"class":193},[130,10287,204],{"class":162},[130,10289,10290],{"class":132,"line":1344},[130,10291,1533],{"class":158},[130,10293,10294,10296,10298,10300,10302,10304,10306,10308,10310,10312,10315,10317,10319,10321,10324,10326],{"class":132,"line":1349},[130,10295,10226],{"class":180},[130,10297,235],{"class":162},[130,10299,9936],{"class":180},[130,10301,235],{"class":162},[130,10303,10235],{"class":180},[130,10305,235],{"class":162},[130,10307,10262],{"class":143},[130,10309,148],{"class":158},[130,10311,201],{"class":193},[130,10313,10314],{"class":197},"Content-Type",[130,10316,201],{"class":193},[130,10318,325],{"class":162},[130,10320,194],{"class":193},[130,10322,10323],{"class":197},"text/plain; charset=utf-8",[130,10325,201],{"class":193},[130,10327,338],{"class":158},[130,10329,10330,10332,10334,10336,10338,10340,10342,10344,10346,10348,10351,10353],{"class":132,"line":1354},[130,10331,10226],{"class":180},[130,10333,235],{"class":162},[130,10335,9936],{"class":180},[130,10337,235],{"class":162},[130,10339,10235],{"class":180},[130,10341,235],{"class":162},[130,10343,7563],{"class":143},[130,10345,148],{"class":158},[130,10347,201],{"class":193},[130,10349,10350],{"class":197},"Access denied",[130,10352,201],{"class":193},[130,10354,338],{"class":158},[130,10356,10357,10359],{"class":132,"line":1359},[130,10358,358],{"class":162},[130,10360,338],{"class":147},[76,10362,5565],{"id":5562},[83,10364,10367],{"className":123,"code":10365,"filename":10366,"language":126,"meta":92,"style":92},"// https://nuxt.com/docs/api/configuration/nuxt-config\nexport default defineNuxtConfig({\n    // ...\n  runtimeConfig: {\n    basicAuth: {\n        // 認証情報を管理する\n      username: 'admin',\n      password: 'admin',\n      allowedRoutes: [],\n    },\n  },\n  // ...\n})\n\n","~/nuxt.config.ts",[90,10368,10369,10374,10386,10391,10400,10409,10414,10430,10445,10456,10460,10466,10471],{"__ignoreMap":92},[130,10370,10371],{"class":132,"line":133},[130,10372,10373],{"class":328},"// https://nuxt.com/docs/api/configuration/nuxt-config\n",[130,10375,10376,10378,10380,10382,10384],{"class":132,"line":155},[130,10377,137],{"class":136},[130,10379,140],{"class":136},[130,10381,5293],{"class":143},[130,10383,148],{"class":147},[130,10385,152],{"class":151},[130,10387,10388],{"class":132,"line":169},[130,10389,10390],{"class":328},"    // ...\n",[130,10392,10393,10396,10398],{"class":132,"line":185},[130,10394,10395],{"class":158},"  runtimeConfig",[130,10397,163],{"class":162},[130,10399,166],{"class":162},[130,10401,10402,10405,10407],{"class":132,"line":207},[130,10403,10404],{"class":158},"    basicAuth",[130,10406,163],{"class":162},[130,10408,166],{"class":162},[130,10410,10411],{"class":132,"line":224},[130,10412,10413],{"class":328},"        // 認証情報を管理する\n",[130,10415,10416,10419,10421,10423,10426,10428],{"class":132,"line":245},[130,10417,10418],{"class":158},"      username",[130,10420,163],{"class":162},[130,10422,194],{"class":193},[130,10424,10425],{"class":197},"admin",[130,10427,201],{"class":193},[130,10429,204],{"class":162},[130,10431,10432,10435,10437,10439,10441,10443],{"class":132,"line":265},[130,10433,10434],{"class":158},"      password",[130,10436,163],{"class":162},[130,10438,194],{"class":193},[130,10440,10425],{"class":197},[130,10442,201],{"class":193},[130,10444,204],{"class":162},[130,10446,10447,10450,10452,10454],{"class":132,"line":283},[130,10448,10449],{"class":158},"      allowedRoutes",[130,10451,163],{"class":162},[130,10453,1974],{"class":180},[130,10455,204],{"class":162},[130,10457,10458],{"class":132,"line":302},[130,10459,5348],{"class":162},[130,10461,10462,10464],{"class":132,"line":332},[130,10463,1981],{"class":162},[130,10465,204],{"class":151},[130,10467,10468],{"class":132,"line":341},[130,10469,10470],{"class":328},"  // ...\n",[130,10472,10473,10475],{"class":132,"line":349},[130,10474,358],{"class":151},[130,10476,338],{"class":147},[16,10478,10479,10480,10482],{},"GitHubに公開したくなければ ",[90,10481,5213],{}," などで管理しましょう。",[11,10484,10485],{"id":10485},"使ってみる",[16,10487,10488],{},"実際に Basic 認証をかけたページを用意してみました。",[16,10490,10491],{},[10492,10493,10497],"a",{"href":10494,"rel":10495},"https://tsukiyama.blog/basic-auth",[10496],"nofollow","Basic認証サンプルページ",[16,10499,10500,10503,10505],{},[90,10501,10502],{},"username: admin",[35,10504],{},[90,10506,10507],{},"password: admin",[16,10509,10510],{},"で通過できます。",[76,10512,10514],{"id":10513},"️-注意","⚠️ 注意",[16,10516,10517,10519,10520,10523],{},[90,10518,9764],{}," に実装しているので、SSR時の画面ロードではBasic 認証がかかりますが、",[106,10521,10522],{},"CSR時にはかかりません","。",[16,10525,10526],{},"ページ全体に認証をかける場合は問題ないのですが、特定のページだけ認証をかけたい場合は以下の対応も必要になります。",[2566,10528,10529,10535],{},[2569,10530,10531,10534],{},[90,10532,10533],{},"middleware/"," にもチェックを追加する",[2569,10536,10537,10538,10541,10542,10545],{},"Basic認証を適用するページへは、クライアントサイドルーティングを避けるために ",[90,10539,10540],{},"\u003CNuxtLink>"," に ",[90,10543,10544],{},"external"," を付けて遷移させる",[16,10547,10548],{},"ただ、特定のページだけ認証を付与するユースケースは一般的ではないと思うので具体的な対応方針については本記事では割愛しています。",[11,10550,5032],{"id":5032},[2566,10552,10553,10559],{},[2569,10554,10555,10556,10558],{},"Nuxt での Basic認証 は ",[90,10557,9764],{}," で実装する",[2569,10560,10561],{},"CSR時にはBasic認証がかからないので別途対応が必要である",[2420,10563,10564],{},"html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sipQf, html code.shiki .sipQf{--shiki-light:#90A4AE;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sfFde, html code.shiki .sfFde{--shiki-light:#39ADB5;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .snYqn, html code.shiki .snYqn{--shiki-light:#E2931D;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sBxIE, html code.shiki .sBxIE{--shiki-light:#FF5370;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sFHE5, html code.shiki .sFHE5{--shiki-light:#F76D47;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":92,"searchDepth":169,"depth":169,"links":10566},[10567,10568,10569,10573,10576],{"id":2464,"depth":155,"text":2464},{"id":9738,"depth":155,"text":9738},{"id":9760,"depth":155,"text":9760,"children":10570},[10571,10572],{"id":9763,"depth":169,"text":9764},{"id":5562,"depth":169,"text":5565},{"id":10485,"depth":155,"text":10485,"children":10574},[10575],{"id":10513,"depth":169,"text":10514},{"id":5032,"depth":155,"text":5032},"2025-06-06T00:00:00.000Z","Nuxt で Basic 認証を実装する備忘録です。",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1749222843/tsukiyama-blog/nuxt-basic-auth/nuxt-basic-auth_kj3jlm.png","/tech/nuxt-basic-auth",{"title":9728,"description":10578},"tech/nuxt-basic-auth",[2452],"N9N6ezA27w3UwTuv-12SLhiXp8Ou-nDsEOuE7Gmf0LA",{"id":10587,"title":10588,"body":10589,"date":12545,"description":12546,"extension":381,"icon":2444,"meta":12547,"navigation":419,"ogImage":12548,"path":12549,"published":419,"publishedAt":2455,"seo":12550,"stem":12551,"tags":12552,"updatedAt":2455,"__hash__":12554},"tech/tech/nuxt-scripts-introduce.md","Nuxt アプリケーションでサードパーティスクリプトを最適化する Nuxt Scripts の紹介",{"type":8,"value":10590,"toc":12529},[10591,10593,10596,10599,10606,10608,10612,10619,10630,10641,10644,10664,10667,10670,10673,10682,10685,10689,10692,10695,10698,11165,11175,11178,11221,11224,11227,11236,11240,11249,11252,11255,11271,12391,12394,12504,12507,12509,12512,12518,12523,12526],[11,10592,2464],{"id":2464},[16,10594,10595],{},"Web サービスを開発する上で、計測タグや広告配信タグなどのサードパーティースクリプトの導入は避けては通れません。",[16,10597,10598],{},"しかし、これらのスクリプトはページ表示速度やユーザー体験を損なう原因になりがちで、特に複数のタグが混在する大規模なアプリケーションでは管理が煩雑になります。",[16,10600,10601,10602,10605],{},"本記事では、Nuxt.js アプリケーションにおける",[106,10603,10604],{},"サードパーティースクリプトの最適化をサポートするモジュール Nuxt Scripts"," について紹介します。",[2523,10607],{"url":5376},[11,10609,10611],{"id":10610},"nuxt-scripts-では何ができるの","Nuxt Scripts では何ができるの？",[16,10613,10614,10615,10618],{},"Nuxt Scripts は、サードパーティースクリプトの",[106,10616,10617],{},"読み込み・管理・最適化","を行うための Nuxt モジュールです。",[16,10620,10621,10622,10625,10626,10629],{},"従来、",[90,10623,10624],{},"\u003Cscript>"," タグを ",[90,10627,10628],{},"useHead()"," などで手動で挿入していた場合、以下のような課題がありました",[2566,10631,10632,10635,10638],{},[2569,10633,10634],{},"読み込みの重複や順序管理が煩雑",[2569,10636,10637],{},"SSR との相性問題（クライアント限定で読み込みたい場面など）",[2569,10639,10640],{},"複数ページ間での再利用性の低さ",[16,10642,10643],{},"Nuxt Scripts を使うと、こうした課題を次のように解決できます",[2566,10645,10646,10652,10655,10661],{},[2569,10647,10648,10651],{},[90,10649,10650],{},"useRegistryScript()"," で script を一元管理",[2569,10653,10654],{},"重複読み込みを自動で防止",[2569,10656,10657,10660],{},[90,10658,10659],{},"onLoaded()"," を使った読み込み完了後の処理",[2569,10662,10663],{},"proxy 経由でグローバルオブジェクトを型安全に扱える",[76,10665,10666],{"id":10666},"利用可能なサードパーティースクリプト",[2523,10668],{"url":10669},"https://scripts.nuxt.com/scripts",[16,10671,10672],{},"こちらのページにすぐに使用できるコンポーザブルがまとまっています。",[16,10674,10675,10676,10678,10679,10681],{},"Google Analytics や X Pixel など、よく使うスクリプトはあらかじめコンポーザブルとして提供されています。",[35,10677],{},"\nよく使われるグローバルなスクリプトは概ね対応済みです。",[35,10680],{},"\n日本のサービスが提供しているスクリプトは基本的にないです。",[16,10683,10684],{},"詳しくは公式ドキュメントをご覧ください。",[11,10686,10688],{"id":10687},"youtube-player-で使ってみる","Youtube Player で使ってみる",[16,10690,10691],{},"今回は、用意されているスクリプトの中の Youtube Player を使ってみます。",[2523,10693],{"url":10694},"https://scripts.nuxt.com/scripts/content/youtube-player",[76,10696,10697],{"id":10697},"コンポーネント",[83,10699,10702],{"className":2137,"code":10700,"filename":10701,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\ndefineProps\u003C{\n  videoId: string;\n}>();\nconst isLoaded = ref(false);\nconst isPlaying = ref(false);\nconst video = ref();\nconst stateChange = (state: { data: number }) => {\n  isPlaying.value = state.data === 1;\n};\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptYouTubePlayer\n    ref=\"video\"\n    :video-id=\"videoId\"\n    @ready=\"isLoaded = true\"\n    @state-change=\"stateChange\"\n  >\n    \u003Ctemplate #awaitingLoad>\n      \u003Cdiv\n        class=\"absolute left-1/2 top-1/2 h-[48px] w-[68px] -translate-x-1/2 -translate-y-1/2 transform\"\n      >\n        \u003Csvg height=\"100%\" version=\"1.1\" viewBox=\"0 0 68 48\" width=\"100%\">\n          \u003Cpath\n            d=\"M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z\"\n            fill=\"#f00\"\n          />\n          \u003Cpath d=\"M 45,24 27,14 27,34\" fill=\"#fff\" />\n        \u003C/svg>\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template>\n","~/components/YouTubePlayer.vue",[90,10703,10704,10724,10731,10743,10751,10771,10790,10805,10836,10862,10867,10875,10879,10887,10894,10907,10921,10935,10949,10953,10967,10973,10987,10992,11049,11057,11071,11085,11090,11122,11131,11140,11148,11157],{"__ignoreMap":92},[130,10705,10706,10708,10710,10712,10714,10716,10718,10720,10722],{"class":132,"line":133},[130,10707,608],{"class":162},[130,10709,5698],{"class":2149},[130,10711,2154],{"class":2153},[130,10713,2157],{"class":2153},[130,10715,2160],{"class":162},[130,10717,2163],{"class":193},[130,10719,126],{"class":197},[130,10721,2163],{"class":193},[130,10723,2170],{"class":162},[130,10725,10726,10729],{"class":132,"line":155},[130,10727,10728],{"class":143},"defineProps",[130,10730,5761],{"class":162},[130,10732,10733,10736,10738,10740],{"class":132,"line":169},[130,10734,10735],{"class":1925},"  videoId",[130,10737,163],{"class":554},[130,10739,581],{"class":580},[130,10741,10742],{"class":162},";\n",[130,10744,10745,10747,10749],{"class":132,"line":185},[130,10746,5787],{"class":162},[130,10748,260],{"class":180},[130,10750,10742],{"class":162},[130,10752,10753,10755,10758,10760,10762,10764,10767,10769],{"class":132,"line":207},[130,10754,1012],{"class":546},[130,10756,10757],{"class":597}," isLoaded",[130,10759,555],{"class":554},[130,10761,5823],{"class":143},[130,10763,148],{"class":180},[130,10765,10766],{"class":1450},"false",[130,10768,584],{"class":180},[130,10770,10742],{"class":162},[130,10772,10773,10775,10778,10780,10782,10784,10786,10788],{"class":132,"line":224},[130,10774,1012],{"class":546},[130,10776,10777],{"class":597}," isPlaying",[130,10779,555],{"class":554},[130,10781,5823],{"class":143},[130,10783,148],{"class":180},[130,10785,10766],{"class":1450},[130,10787,584],{"class":180},[130,10789,10742],{"class":162},[130,10791,10792,10794,10797,10799,10801,10803],{"class":132,"line":245},[130,10793,1012],{"class":546},[130,10795,10796],{"class":597}," video",[130,10798,555],{"class":554},[130,10800,5823],{"class":143},[130,10802,260],{"class":180},[130,10804,10742],{"class":162},[130,10806,10807,10809,10812,10814,10816,10819,10821,10823,10825,10827,10829,10832,10834],{"class":132,"line":265},[130,10808,1012],{"class":546},[130,10810,10811],{"class":550}," stateChange",[130,10813,555],{"class":554},[130,10815,561],{"class":162},[130,10817,10818],{"class":564},"state",[130,10820,163],{"class":554},[130,10822,499],{"class":162},[130,10824,1926],{"class":1925},[130,10826,163],{"class":554},[130,10828,5731],{"class":580},[130,10830,10831],{"class":162}," })",[130,10833,587],{"class":546},[130,10835,166],{"class":162},[130,10837,10838,10841,10843,10845,10847,10850,10852,10855,10857,10860],{"class":132,"line":283},[130,10839,10840],{"class":180},"  isPlaying",[130,10842,235],{"class":162},[130,10844,5922],{"class":180},[130,10846,555],{"class":554},[130,10848,10849],{"class":180}," state",[130,10851,235],{"class":162},[130,10853,10854],{"class":180},"data",[130,10856,1167],{"class":554},[130,10858,10859],{"class":2349}," 1",[130,10861,10742],{"class":162},[130,10863,10864],{"class":132,"line":302},[130,10865,10866],{"class":162},"};\n",[130,10868,10869,10871,10873],{"class":132,"line":332},[130,10870,2193],{"class":162},[130,10872,5698],{"class":2149},[130,10874,2170],{"class":162},[130,10876,10877],{"class":132,"line":341},[130,10878,420],{"emptyLinePlaceholder":419},[130,10880,10881,10883,10885],{"class":132,"line":349},[130,10882,608],{"class":162},[130,10884,2130],{"class":2149},[130,10886,2170],{"class":162},[130,10888,10889,10891],{"class":132,"line":355},[130,10890,2989],{"class":162},[130,10892,10893],{"class":2149},"ScriptYouTubePlayer\n",[130,10895,10896,10898,10900,10902,10905],{"class":132,"line":783},[130,10897,6159],{"class":2153},[130,10899,2160],{"class":162},[130,10901,2163],{"class":193},[130,10903,10904],{"class":197},"video",[130,10906,2789],{"class":193},[130,10908,10909,10912,10914,10916,10919],{"class":132,"line":793},[130,10910,10911],{"class":2153},"    :video-id",[130,10913,2160],{"class":162},[130,10915,2163],{"class":193},[130,10917,10918],{"class":197},"videoId",[130,10920,2789],{"class":193},[130,10922,10923,10926,10928,10930,10933],{"class":132,"line":798},[130,10924,10925],{"class":2153},"    @ready",[130,10927,2160],{"class":162},[130,10929,2163],{"class":193},[130,10931,10932],{"class":197},"isLoaded = true",[130,10934,2789],{"class":193},[130,10936,10937,10940,10942,10944,10947],{"class":132,"line":806},[130,10938,10939],{"class":2153},"    @state-change",[130,10941,2160],{"class":162},[130,10943,2163],{"class":193},[130,10945,10946],{"class":197},"stateChange",[130,10948,2789],{"class":193},[130,10950,10951],{"class":132,"line":1073},[130,10952,3521],{"class":162},[130,10954,10955,10957,10959,10962,10965],{"class":132,"line":1086},[130,10956,3010],{"class":162},[130,10958,2130],{"class":2149},[130,10960,10961],{"class":162}," #",[130,10963,10964],{"class":2153},"awaitingLoad",[130,10966,2170],{"class":162},[130,10968,10969,10971],{"class":132,"line":1092},[130,10970,3030],{"class":162},[130,10972,6154],{"class":2149},[130,10974,10975,10978,10980,10982,10985],{"class":132,"line":1128},[130,10976,10977],{"class":2153},"        class",[130,10979,2160],{"class":162},[130,10981,2163],{"class":193},[130,10983,10984],{"class":197},"absolute left-1/2 top-1/2 h-[48px] w-[68px] -translate-x-1/2 -translate-y-1/2 transform",[130,10986,2789],{"class":193},[130,10988,10989],{"class":132,"line":1151},[130,10990,10991],{"class":162},"      >\n",[130,10993,10994,10997,11000,11003,11005,11007,11010,11012,11015,11017,11019,11022,11024,11027,11029,11031,11034,11036,11039,11041,11043,11045,11047],{"class":132,"line":1156},[130,10995,10996],{"class":162},"        \u003C",[130,10998,10999],{"class":2149},"svg",[130,11001,11002],{"class":2153}," height",[130,11004,2160],{"class":162},[130,11006,2163],{"class":193},[130,11008,11009],{"class":197},"100%",[130,11011,2163],{"class":193},[130,11013,11014],{"class":2153}," version",[130,11016,2160],{"class":162},[130,11018,2163],{"class":193},[130,11020,11021],{"class":197},"1.1",[130,11023,2163],{"class":193},[130,11025,11026],{"class":2153}," viewBox",[130,11028,2160],{"class":162},[130,11030,2163],{"class":193},[130,11032,11033],{"class":197},"0 0 68 48",[130,11035,2163],{"class":193},[130,11037,11038],{"class":2153}," width",[130,11040,2160],{"class":162},[130,11042,2163],{"class":193},[130,11044,11009],{"class":197},[130,11046,2163],{"class":193},[130,11048,2170],{"class":162},[130,11050,11051,11054],{"class":132,"line":1179},[130,11052,11053],{"class":162},"          \u003C",[130,11055,11056],{"class":2149},"path\n",[130,11058,11059,11062,11064,11066,11069],{"class":132,"line":1188},[130,11060,11061],{"class":2153},"            d",[130,11063,2160],{"class":162},[130,11065,2163],{"class":193},[130,11067,11068],{"class":197},"M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z",[130,11070,2789],{"class":193},[130,11072,11073,11076,11078,11080,11083],{"class":132,"line":1193},[130,11074,11075],{"class":2153},"            fill",[130,11077,2160],{"class":162},[130,11079,2163],{"class":193},[130,11081,11082],{"class":197},"#f00",[130,11084,2789],{"class":193},[130,11086,11087],{"class":132,"line":1198},[130,11088,11089],{"class":162},"          />\n",[130,11091,11092,11094,11096,11099,11101,11103,11106,11108,11111,11113,11115,11118,11120],{"class":132,"line":1222},[130,11093,11053],{"class":162},[130,11095,640],{"class":2149},[130,11097,11098],{"class":2153}," d",[130,11100,2160],{"class":162},[130,11102,2163],{"class":193},[130,11104,11105],{"class":197},"M 45,24 27,14 27,34",[130,11107,2163],{"class":193},[130,11109,11110],{"class":2153}," fill",[130,11112,2160],{"class":162},[130,11114,2163],{"class":193},[130,11116,11117],{"class":197},"#fff",[130,11119,2163],{"class":193},[130,11121,6269],{"class":162},[130,11123,11124,11127,11129],{"class":132,"line":1227},[130,11125,11126],{"class":162},"        \u003C/",[130,11128,10999],{"class":2149},[130,11130,2170],{"class":162},[130,11132,11133,11136,11138],{"class":132,"line":1232},[130,11134,11135],{"class":162},"      \u003C/",[130,11137,2683],{"class":2149},[130,11139,2170],{"class":162},[130,11141,11142,11144,11146],{"class":132,"line":1237},[130,11143,3042],{"class":162},[130,11145,2130],{"class":2149},[130,11147,2170],{"class":162},[130,11149,11150,11152,11155],{"class":132,"line":1243},[130,11151,3051],{"class":162},[130,11153,11154],{"class":2149},"ScriptYouTubePlayer",[130,11156,2170],{"class":162},[130,11158,11159,11161,11163],{"class":132,"line":1256},[130,11160,2193],{"class":162},[130,11162,2130],{"class":2149},[130,11164,2170],{"class":162},[16,11166,11167,11170,11171,11174],{},[90,11168,11169],{},"\u003CScriptYouTubePlayer>"," を呼びつつ ",[90,11172,11173],{},"slot"," 内に再生ボタンをおきます。",[76,11176,11177],{"id":11177},"テンプレート",[83,11179,11182],{"className":2137,"code":11180,"filename":11181,"language":2140,"meta":92,"style":92},"\u003Ctemplate>\n  \u003CYouTubePlayer video-id=\"xxx\" />\n\u003C/template>\n","~/pages/index.vue",[90,11183,11184,11192,11213],{"__ignoreMap":92},[130,11185,11186,11188,11190],{"class":132,"line":133},[130,11187,608],{"class":162},[130,11189,2130],{"class":2149},[130,11191,2170],{"class":162},[130,11193,11194,11196,11199,11202,11204,11206,11209,11211],{"class":132,"line":155},[130,11195,2989],{"class":162},[130,11197,11198],{"class":2149},"YouTubePlayer",[130,11200,11201],{"class":2153}," video-id",[130,11203,2160],{"class":162},[130,11205,2163],{"class":193},[130,11207,11208],{"class":197},"xxx",[130,11210,2163],{"class":193},[130,11212,6269],{"class":162},[130,11214,11215,11217,11219],{"class":132,"line":169},[130,11216,2193],{"class":162},[130,11218,2130],{"class":2149},[130,11220,2170],{"class":162},[16,11222,11223],{},"props として videoId を渡します。",[76,11225,11226],{"id":11226},"表示はこんな感じ",[2683,11228,11232],{"className":11229},[11230,11231],"rounded-md","overflow-hidden",[11233,11234],"you-tube-player",{"video-id":11235},"d_IFKP1Ofq0",[11,11237,11239],{"id":11238},"script-registry-に登録されていないスクリプトの読み込み","Script Registry に登録されていないスクリプトの読み込み",[16,11241,11242,11245,11246,11248],{},[90,11243,11244],{},"Script Registry"," に用意されていないスクリプトも ",[90,11247,10650],{}," を使うことで読み込めます。",[16,11250,11251],{},"今回は Tiktok Pixel タグの設定を例に進めていきます。",[76,11253,11254],{"id":11254},"コンポーザブル",[16,11256,11257,11260,11261,11263,11264,11270],{},[90,11258,11259],{},"ttq"," の Proxy オブジェクトを提供するコンポーザブルを作成します。",[35,11262],{},"\n（※あくまでサンプル実装であり、実運用を保証するものではありません。正しく Tiktok Pixel タグを設定したいかたは",[10492,11265,11269],{"href":11266,"rel":11267,"target":11268},"https://github.com/nuxt/scripts/discussions/177#discussioncomment-10128841",[10496],"_blank","こちらを参考","に実装してください",[83,11272,11275],{"className":123,"code":11273,"filename":11274,"language":126,"meta":92,"style":92},"export const useTiktokPixel = () => {\n  // runtimeConfig などで sdkId を管理する\n  const { sdkId } = useRuntimeConfig();\n  const { proxy, onLoaded } = useRegistryScript(\"karte\", () => ({\n    scriptInput: {\n      src: `https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=${sdkId}&lib=ttq`,\n      crossorigin: false,\n    },\n    scriptOptions: {\n      use() {\n        return { ttq: window.ttq }\n      },\n    },\n    clientInit: () => {\n      // @ts-expect-error Tiktok提供スクリプトのため型エラーを許容している\n      // prettier-ignore\n      // eslint-disable-next-line\n      !function (w, d, t) {w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=[\"page\",\"track\",\"identify\",\"instances\",\"debug\",\"on\",\"off\",\"once\",\"ready\",\"alias\",\"group\",\"enableCookie\",\"disableCookie\", \"holdConsent\", \"revokeConsent\", \"grantConsent\"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i\u003Cttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n\u003Cttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e},ttq.load=function(e,n){var i=\"https://analytics.tiktok.com/i18n/pixel/events.js\";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement(\"script\");o.type=\"text/javascript\",o.async=!0,o.src=i+\"?sdkid=\"+e+\"&lib=\"+t;var a=document.getElementsByTagName(\"script\")[0];a.parentNode.insertBefore(o,a)};ttq.load(sdkId)}(window, document, 'ttq');\n    }\n  }))\n\n  return {\n    proxy,\n    onLoaded,\n  }\n}\n","~/composables/analytics/tiktok.ts",[90,11276,11277,11294,11299,11318,11357,11366,11392,11404,11408,11417,11427,11448,11452,11456,11469,11474,11479,11484,12349,12353,12359,12363,12369,12376,12383,12387],{"__ignoreMap":92},[130,11278,11279,11281,11283,11286,11288,11290,11292],{"class":132,"line":133},[130,11280,137],{"class":136},[130,11282,547],{"class":546},[130,11284,11285],{"class":550}," useTiktokPixel",[130,11287,555],{"class":554},[130,11289,1912],{"class":162},[130,11291,587],{"class":546},[130,11293,166],{"class":162},[130,11295,11296],{"class":132,"line":155},[130,11297,11298],{"class":328},"  // runtimeConfig などで sdkId を管理する\n",[130,11300,11301,11303,11305,11308,11310,11312,11314,11316],{"class":132,"line":169},[130,11302,594],{"class":546},[130,11304,499],{"class":162},[130,11306,11307],{"class":597}," sdkId",[130,11309,505],{"class":162},[130,11311,555],{"class":554},[130,11313,5805],{"class":143},[130,11315,260],{"class":158},[130,11317,10742],{"class":162},[130,11319,11320,11322,11324,11327,11329,11331,11333,11335,11338,11340,11342,11345,11347,11349,11351,11353,11355],{"class":132,"line":185},[130,11321,594],{"class":546},[130,11323,499],{"class":162},[130,11325,11326],{"class":597}," proxy",[130,11328,325],{"class":162},[130,11330,5854],{"class":597},[130,11332,505],{"class":162},[130,11334,555],{"class":554},[130,11336,11337],{"class":143}," useRegistryScript",[130,11339,148],{"class":158},[130,11341,2163],{"class":193},[130,11343,11344],{"class":197},"karte",[130,11346,2163],{"class":193},[130,11348,325],{"class":162},[130,11350,1912],{"class":162},[130,11352,587],{"class":546},[130,11354,561],{"class":158},[130,11356,152],{"class":162},[130,11358,11359,11362,11364],{"class":132,"line":207},[130,11360,11361],{"class":158},"    scriptInput",[130,11363,163],{"class":162},[130,11365,166],{"class":162},[130,11367,11368,11370,11372,11375,11378,11380,11383,11385,11388,11390],{"class":132,"line":224},[130,11369,4411],{"class":158},[130,11371,163],{"class":162},[130,11373,11374],{"class":193}," `",[130,11376,11377],{"class":197},"https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=",[130,11379,651],{"class":193},[130,11381,11382],{"class":180},"sdkId",[130,11384,358],{"class":193},[130,11386,11387],{"class":197},"&lib=ttq",[130,11389,645],{"class":193},[130,11391,204],{"class":162},[130,11393,11394,11397,11399,11402],{"class":132,"line":245},[130,11395,11396],{"class":158},"      crossorigin",[130,11398,163],{"class":162},[130,11400,11401],{"class":1450}," false",[130,11403,204],{"class":162},[130,11405,11406],{"class":132,"line":265},[130,11407,5348],{"class":162},[130,11409,11410,11413,11415],{"class":132,"line":283},[130,11411,11412],{"class":158},"    scriptOptions",[130,11414,163],{"class":162},[130,11416,166],{"class":162},[130,11418,11419,11423,11425],{"class":132,"line":302},[130,11420,11422],{"class":11421},"sDDeY","      use",[130,11424,260],{"class":162},[130,11426,166],{"class":162},[130,11428,11429,11432,11434,11437,11439,11442,11444,11446],{"class":132,"line":332},[130,11430,11431],{"class":136},"        return",[130,11433,499],{"class":162},[130,11435,11436],{"class":158}," ttq",[130,11438,163],{"class":162},[130,11440,11441],{"class":180}," window",[130,11443,235],{"class":162},[130,11445,11259],{"class":180},[130,11447,1998],{"class":162},[130,11449,11450],{"class":132,"line":341},[130,11451,5343],{"class":162},[130,11453,11454],{"class":132,"line":349},[130,11455,5348],{"class":162},[130,11457,11458,11461,11463,11465,11467],{"class":132,"line":355},[130,11459,11460],{"class":143},"    clientInit",[130,11462,163],{"class":162},[130,11464,1912],{"class":162},[130,11466,587],{"class":546},[130,11468,166],{"class":162},[130,11470,11471],{"class":132,"line":783},[130,11472,11473],{"class":328},"      // @ts-expect-error Tiktok提供スクリプトのため型エラーを許容している\n",[130,11475,11476],{"class":132,"line":793},[130,11477,11478],{"class":328},"      // prettier-ignore\n",[130,11480,11481],{"class":132,"line":798},[130,11482,11483],{"class":328},"      // eslint-disable-next-line\n",[130,11485,11486,11489,11492,11494,11496,11498,11500,11502,11505,11507,11509,11511,11513,11516,11518,11521,11524,11527,11529,11531,11533,11536,11538,11540,11542,11544,11546,11548,11550,11553,11556,11558,11560,11562,11565,11567,11569,11571,11573,11575,11577,11579,11582,11584,11586,11588,11591,11593,11595,11597,11600,11602,11604,11606,11609,11611,11613,11615,11618,11620,11622,11624,11627,11629,11631,11633,11636,11638,11640,11642,11645,11647,11649,11651,11654,11656,11658,11660,11663,11665,11667,11669,11672,11674,11676,11678,11681,11683,11685,11688,11691,11693,11695,11697,11700,11702,11704,11706,11709,11711,11713,11715,11717,11719,11722,11724,11726,11728,11730,11732,11735,11738,11740,11742,11744,11746,11748,11750,11753,11755,11757,11760,11763,11765,11767,11769,11772,11774,11777,11779,11782,11784,11787,11789,11792,11794,11797,11799,11802,11805,11808,11811,11813,11815,11818,11820,11822,11824,11827,11829,11831,11833,11835,11837,11840,11842,11844,11847,11849,11851,11853,11855,11857,11859,11861,11863,11865,11867,11869,11871,11874,11876,11878,11880,11882,11884,11886,11888,11890,11892,11894,11896,11898,11901,11903,11905,11907,11910,11912,11914,11916,11918,11920,11922,11925,11927,11929,11931,11933,11935,11937,11939,11941,11943,11945,11947,11949,11951,11953,11955,11957,11959,11961,11963,11965,11967,11969,11971,11973,11975,11977,11979,11982,11984,11987,11989,11991,11994,11996,11998,12000,12002,12004,12006,12008,12010,12012,12014,12016,12019,12021,12023,12025,12027,12029,12031,12033,12035,12037,12039,12042,12044,12046,12048,12050,12052,12054,12056,12058,12060,12062,12064,12066,12068,12070,12072,12074,12077,12079,12081,12083,12085,12087,12090,12092,12094,12096,12098,12100,12102,12104,12106,12108,12110,12112,12114,12117,12120,12122,12124,12126,12129,12131,12133,12135,12137,12139,12141,12143,12145,12147,12149,12151,12153,12155,12157,12159,12162,12164,12167,12169,12172,12174,12177,12179,12181,12183,12185,12187,12189,12192,12194,12196,12198,12200,12203,12205,12207,12209,12211,12213,12216,12218,12220,12222,12224,12226,12228,12230,12232,12234,12237,12239,12241,12243,12245,12247,12250,12252,12254,12256,12258,12260,12263,12265,12267,12269,12272,12274,12276,12278,12280,12282,12284,12286,12288,12290,12292,12295,12297,12300,12302,12304,12306,12308,12310,12313,12315,12317,12319,12321,12323,12325,12327,12329,12332,12334,12337,12339,12341,12343,12345,12347],{"class":132,"line":806},[130,11487,11488],{"class":554},"      !",[130,11490,11491],{"class":546},"function",[130,11493,561],{"class":162},[130,11495,2941],{"class":564},[130,11497,325],{"class":162},[130,11499,11098],{"class":564},[130,11501,325],{"class":162},[130,11503,11504],{"class":564}," t",[130,11506,584],{"class":162},[130,11508,499],{"class":162},[130,11510,2941],{"class":180},[130,11512,235],{"class":162},[130,11514,11515],{"class":180},"TiktokAnalyticsObject",[130,11517,2160],{"class":554},[130,11519,11520],{"class":180},"t",[130,11522,11523],{"class":162},";",[130,11525,11526],{"class":546},"var",[130,11528,11436],{"class":180},[130,11530,2160],{"class":554},[130,11532,2941],{"class":180},[130,11534,11535],{"class":158},"[",[130,11537,11520],{"class":180},[130,11539,10090],{"class":158},[130,11541,2160],{"class":554},[130,11543,2941],{"class":180},[130,11545,11535],{"class":158},[130,11547,11520],{"class":180},[130,11549,10090],{"class":158},[130,11551,11552],{"class":554},"||",[130,11554,11555],{"class":158},"[]",[130,11557,11523],{"class":162},[130,11559,11259],{"class":180},[130,11561,235],{"class":162},[130,11563,11564],{"class":180},"methods",[130,11566,2160],{"class":554},[130,11568,11535],{"class":158},[130,11570,2163],{"class":193},[130,11572,198],{"class":197},[130,11574,2163],{"class":193},[130,11576,325],{"class":162},[130,11578,2163],{"class":193},[130,11580,11581],{"class":197},"track",[130,11583,2163],{"class":193},[130,11585,325],{"class":162},[130,11587,2163],{"class":193},[130,11589,11590],{"class":197},"identify",[130,11592,2163],{"class":193},[130,11594,325],{"class":162},[130,11596,2163],{"class":193},[130,11598,11599],{"class":197},"instances",[130,11601,2163],{"class":193},[130,11603,325],{"class":162},[130,11605,2163],{"class":193},[130,11607,11608],{"class":197},"debug",[130,11610,2163],{"class":193},[130,11612,325],{"class":162},[130,11614,2163],{"class":193},[130,11616,11617],{"class":197},"on",[130,11619,2163],{"class":193},[130,11621,325],{"class":162},[130,11623,2163],{"class":193},[130,11625,11626],{"class":197},"off",[130,11628,2163],{"class":193},[130,11630,325],{"class":162},[130,11632,2163],{"class":193},[130,11634,11635],{"class":197},"once",[130,11637,2163],{"class":193},[130,11639,325],{"class":162},[130,11641,2163],{"class":193},[130,11643,11644],{"class":197},"ready",[130,11646,2163],{"class":193},[130,11648,325],{"class":162},[130,11650,2163],{"class":193},[130,11652,11653],{"class":197},"alias",[130,11655,2163],{"class":193},[130,11657,325],{"class":162},[130,11659,2163],{"class":193},[130,11661,11662],{"class":197},"group",[130,11664,2163],{"class":193},[130,11666,325],{"class":162},[130,11668,2163],{"class":193},[130,11670,11671],{"class":197},"enableCookie",[130,11673,2163],{"class":193},[130,11675,325],{"class":162},[130,11677,2163],{"class":193},[130,11679,11680],{"class":197},"disableCookie",[130,11682,2163],{"class":193},[130,11684,325],{"class":162},[130,11686,11687],{"class":193}," \"",[130,11689,11690],{"class":197},"holdConsent",[130,11692,2163],{"class":193},[130,11694,325],{"class":162},[130,11696,11687],{"class":193},[130,11698,11699],{"class":197},"revokeConsent",[130,11701,2163],{"class":193},[130,11703,325],{"class":162},[130,11705,11687],{"class":193},[130,11707,11708],{"class":197},"grantConsent",[130,11710,2163],{"class":193},[130,11712,10090],{"class":158},[130,11714,325],{"class":162},[130,11716,11259],{"class":180},[130,11718,235],{"class":162},[130,11720,11721],{"class":143},"setAndDefer",[130,11723,2160],{"class":554},[130,11725,11491],{"class":546},[130,11727,148],{"class":162},[130,11729,11520],{"class":564},[130,11731,325],{"class":162},[130,11733,11734],{"class":564},"e",[130,11736,11737],{"class":162},"){",[130,11739,11520],{"class":180},[130,11741,11535],{"class":158},[130,11743,11734],{"class":180},[130,11745,10090],{"class":158},[130,11747,2160],{"class":554},[130,11749,11491],{"class":546},[130,11751,11752],{"class":162},"(){",[130,11754,11520],{"class":180},[130,11756,235],{"class":162},[130,11758,11759],{"class":143},"push",[130,11761,11762],{"class":158},"([",[130,11764,11734],{"class":180},[130,11766,10090],{"class":158},[130,11768,235],{"class":162},[130,11770,11771],{"class":143},"concat",[130,11773,148],{"class":158},[130,11775,11776],{"class":580},"Array",[130,11778,235],{"class":162},[130,11780,11781],{"class":597},"prototype",[130,11783,235],{"class":162},[130,11785,11786],{"class":180},"slice",[130,11788,235],{"class":162},[130,11790,11791],{"class":143},"call",[130,11793,148],{"class":158},[130,11795,11796],{"class":597},"arguments",[130,11798,325],{"class":162},[130,11800,11801],{"class":2349},"0",[130,11803,11804],{"class":158},")))",[130,11806,11807],{"class":162},"}};",[130,11809,11810],{"class":136},"for",[130,11812,148],{"class":158},[130,11814,11526],{"class":546},[130,11816,11817],{"class":180}," i",[130,11819,2160],{"class":554},[130,11821,11801],{"class":2349},[130,11823,11523],{"class":162},[130,11825,11826],{"class":180},"i",[130,11828,608],{"class":554},[130,11830,11259],{"class":180},[130,11832,235],{"class":162},[130,11834,11564],{"class":180},[130,11836,235],{"class":162},[130,11838,11839],{"class":597},"length",[130,11841,11523],{"class":162},[130,11843,11826],{"class":180},[130,11845,11846],{"class":554},"++",[130,11848,584],{"class":158},[130,11850,11259],{"class":180},[130,11852,235],{"class":162},[130,11854,11721],{"class":143},[130,11856,148],{"class":158},[130,11858,11259],{"class":180},[130,11860,325],{"class":162},[130,11862,11259],{"class":180},[130,11864,235],{"class":162},[130,11866,11564],{"class":180},[130,11868,11535],{"class":158},[130,11870,11826],{"class":180},[130,11872,11873],{"class":158},"])",[130,11875,11523],{"class":162},[130,11877,11259],{"class":180},[130,11879,235],{"class":162},[130,11881,5899],{"class":143},[130,11883,2160],{"class":554},[130,11885,11491],{"class":546},[130,11887,148],{"class":162},[130,11889,11520],{"class":564},[130,11891,11737],{"class":162},[130,11893,11810],{"class":136},[130,11895,148],{"class":158},[130,11897,11526],{"class":546},[130,11899,11900],{"class":180}," e",[130,11902,2160],{"class":554},[130,11904,11259],{"class":180},[130,11906,235],{"class":162},[130,11908,11909],{"class":180},"_i",[130,11911,11535],{"class":158},[130,11913,11520],{"class":180},[130,11915,10090],{"class":158},[130,11917,11552],{"class":554},[130,11919,11555],{"class":158},[130,11921,325],{"class":162},[130,11923,11924],{"class":180},"n",[130,11926,2160],{"class":554},[130,11928,11801],{"class":2349},[130,11930,11523],{"class":162},[130,11932,11924],{"class":180},[130,11934,608],{"class":554},[130,11936,11259],{"class":180},[130,11938,235],{"class":162},[130,11940,11564],{"class":180},[130,11942,235],{"class":162},[130,11944,11839],{"class":597},[130,11946,11523],{"class":162},[130,11948,11924],{"class":180},[130,11950,11846],{"class":554},[130,11952,584],{"class":158},[130,11954,11259],{"class":180},[130,11956,235],{"class":162},[130,11958,11721],{"class":143},[130,11960,148],{"class":158},[130,11962,11734],{"class":180},[130,11964,325],{"class":162},[130,11966,11259],{"class":180},[130,11968,235],{"class":162},[130,11970,11564],{"class":180},[130,11972,11535],{"class":158},[130,11974,11924],{"class":180},[130,11976,11873],{"class":158},[130,11978,11523],{"class":162},[130,11980,11981],{"class":136},"return",[130,11983,11900],{"class":180},[130,11985,11986],{"class":162},"},",[130,11988,11259],{"class":180},[130,11990,235],{"class":162},[130,11992,11993],{"class":143},"load",[130,11995,2160],{"class":554},[130,11997,11491],{"class":546},[130,11999,148],{"class":162},[130,12001,11734],{"class":564},[130,12003,325],{"class":162},[130,12005,11924],{"class":564},[130,12007,11737],{"class":162},[130,12009,11526],{"class":546},[130,12011,11817],{"class":180},[130,12013,2160],{"class":554},[130,12015,2163],{"class":193},[130,12017,12018],{"class":197},"https://analytics.tiktok.com/i18n/pixel/events.js",[130,12020,2163],{"class":193},[130,12022,11523],{"class":162},[130,12024,11259],{"class":180},[130,12026,235],{"class":162},[130,12028,11909],{"class":180},[130,12030,2160],{"class":554},[130,12032,11259],{"class":180},[130,12034,235],{"class":162},[130,12036,11909],{"class":180},[130,12038,11552],{"class":554},[130,12040,12041],{"class":162},"{},",[130,12043,11259],{"class":180},[130,12045,235],{"class":162},[130,12047,11909],{"class":180},[130,12049,11535],{"class":158},[130,12051,11734],{"class":180},[130,12053,10090],{"class":158},[130,12055,2160],{"class":554},[130,12057,11555],{"class":158},[130,12059,325],{"class":162},[130,12061,11259],{"class":180},[130,12063,235],{"class":162},[130,12065,11909],{"class":180},[130,12067,11535],{"class":158},[130,12069,11734],{"class":180},[130,12071,10090],{"class":158},[130,12073,235],{"class":162},[130,12075,12076],{"class":180},"_u",[130,12078,2160],{"class":554},[130,12080,11826],{"class":180},[130,12082,325],{"class":162},[130,12084,11259],{"class":180},[130,12086,235],{"class":162},[130,12088,12089],{"class":180},"_t",[130,12091,2160],{"class":554},[130,12093,11259],{"class":180},[130,12095,235],{"class":162},[130,12097,12089],{"class":180},[130,12099,11552],{"class":554},[130,12101,12041],{"class":162},[130,12103,11259],{"class":180},[130,12105,235],{"class":162},[130,12107,12089],{"class":180},[130,12109,11535],{"class":158},[130,12111,11734],{"class":180},[130,12113,10090],{"class":158},[130,12115,12116],{"class":554},"=+new",[130,12118,12119],{"class":180}," Date",[130,12121,325],{"class":162},[130,12123,11259],{"class":180},[130,12125,235],{"class":162},[130,12127,12128],{"class":180},"_o",[130,12130,2160],{"class":554},[130,12132,11259],{"class":180},[130,12134,235],{"class":162},[130,12136,12128],{"class":180},[130,12138,11552],{"class":554},[130,12140,12041],{"class":162},[130,12142,11259],{"class":180},[130,12144,235],{"class":162},[130,12146,12128],{"class":180},[130,12148,11535],{"class":158},[130,12150,11734],{"class":180},[130,12152,10090],{"class":158},[130,12154,2160],{"class":554},[130,12156,11924],{"class":180},[130,12158,11552],{"class":554},[130,12160,12161],{"class":162},"{};",[130,12163,11526],{"class":546},[130,12165,12166],{"class":180}," o",[130,12168,2160],{"class":554},[130,12170,12171],{"class":180},"document",[130,12173,235],{"class":162},[130,12175,12176],{"class":143},"createElement",[130,12178,148],{"class":158},[130,12180,2163],{"class":193},[130,12182,5698],{"class":197},[130,12184,2163],{"class":193},[130,12186,584],{"class":158},[130,12188,11523],{"class":162},[130,12190,12191],{"class":180},"o",[130,12193,235],{"class":162},[130,12195,3726],{"class":180},[130,12197,2160],{"class":554},[130,12199,2163],{"class":193},[130,12201,12202],{"class":197},"text/javascript",[130,12204,2163],{"class":193},[130,12206,325],{"class":162},[130,12208,12191],{"class":180},[130,12210,235],{"class":162},[130,12212,1622],{"class":180},[130,12214,12215],{"class":554},"=!",[130,12217,11801],{"class":2349},[130,12219,325],{"class":162},[130,12221,12191],{"class":180},[130,12223,235],{"class":162},[130,12225,4818],{"class":180},[130,12227,2160],{"class":554},[130,12229,11826],{"class":180},[130,12231,5538],{"class":554},[130,12233,2163],{"class":193},[130,12235,12236],{"class":197},"?sdkid=",[130,12238,2163],{"class":193},[130,12240,5538],{"class":554},[130,12242,11734],{"class":180},[130,12244,5538],{"class":554},[130,12246,2163],{"class":193},[130,12248,12249],{"class":197},"&lib=",[130,12251,2163],{"class":193},[130,12253,5538],{"class":554},[130,12255,11520],{"class":180},[130,12257,11523],{"class":162},[130,12259,11526],{"class":546},[130,12261,12262],{"class":180}," a",[130,12264,2160],{"class":554},[130,12266,12171],{"class":180},[130,12268,235],{"class":162},[130,12270,12271],{"class":143},"getElementsByTagName",[130,12273,148],{"class":158},[130,12275,2163],{"class":193},[130,12277,5698],{"class":197},[130,12279,2163],{"class":193},[130,12281,10044],{"class":158},[130,12283,11801],{"class":2349},[130,12285,10090],{"class":158},[130,12287,11523],{"class":162},[130,12289,10492],{"class":180},[130,12291,235],{"class":162},[130,12293,12294],{"class":180},"parentNode",[130,12296,235],{"class":162},[130,12298,12299],{"class":143},"insertBefore",[130,12301,148],{"class":158},[130,12303,12191],{"class":180},[130,12305,325],{"class":162},[130,12307,10492],{"class":180},[130,12309,584],{"class":158},[130,12311,12312],{"class":162},"};",[130,12314,11259],{"class":180},[130,12316,235],{"class":162},[130,12318,11993],{"class":143},[130,12320,148],{"class":158},[130,12322,11382],{"class":180},[130,12324,584],{"class":158},[130,12326,358],{"class":162},[130,12328,148],{"class":158},[130,12330,12331],{"class":180},"window",[130,12333,325],{"class":162},[130,12335,12336],{"class":180}," document",[130,12338,325],{"class":162},[130,12340,194],{"class":193},[130,12342,11259],{"class":197},[130,12344,201],{"class":193},[130,12346,584],{"class":158},[130,12348,10742],{"class":162},[130,12350,12351],{"class":132,"line":1073},[130,12352,2105],{"class":162},[130,12354,12355,12357],{"class":132,"line":1086},[130,12356,1981],{"class":162},[130,12358,8727],{"class":158},[130,12360,12361],{"class":132,"line":1092},[130,12362,420],{"emptyLinePlaceholder":419},[130,12364,12365,12367],{"class":132,"line":1128},[130,12366,678],{"class":136},[130,12368,166],{"class":162},[130,12370,12371,12374],{"class":132,"line":1151},[130,12372,12373],{"class":180},"    proxy",[130,12375,204],{"class":162},[130,12377,12378,12381],{"class":132,"line":1156},[130,12379,12380],{"class":180},"    onLoaded",[130,12382,204],{"class":162},[130,12384,12385],{"class":132,"line":1179},[130,12386,352],{"class":162},[130,12388,12389],{"class":132,"line":1188},[130,12390,686],{"class":162},[76,12392,11177],{"id":12393},"テンプレート-1",[83,12395,12397],{"className":2137,"code":12396,"filename":11181,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nimport { useTiktokPixel } from '~/composables/analytics/tiktok'\n\n// Tiktok Pixelタグ\nconst { proxy } = useTiktokPixel()\nonMounted(() => {\n  proxy.ttq.page()\n})\n\u003C/script>\n\n",[90,12398,12399,12419,12438,12442,12447,12463,12475,12490,12496],{"__ignoreMap":92},[130,12400,12401,12403,12405,12407,12409,12411,12413,12415,12417],{"class":132,"line":133},[130,12402,608],{"class":162},[130,12404,5698],{"class":2149},[130,12406,2154],{"class":2153},[130,12408,2157],{"class":2153},[130,12410,2160],{"class":162},[130,12412,2163],{"class":193},[130,12414,126],{"class":197},[130,12416,2163],{"class":193},[130,12418,2170],{"class":162},[130,12420,12421,12423,12425,12427,12429,12431,12433,12436],{"class":132,"line":155},[130,12422,493],{"class":136},[130,12424,499],{"class":162},[130,12426,11285],{"class":180},[130,12428,505],{"class":162},[130,12430,508],{"class":136},[130,12432,194],{"class":193},[130,12434,12435],{"class":197},"~/composables/analytics/tiktok",[130,12437,515],{"class":193},[130,12439,12440],{"class":132,"line":169},[130,12441,420],{"emptyLinePlaceholder":419},[130,12443,12444],{"class":132,"line":185},[130,12445,12446],{"class":328},"// Tiktok Pixelタグ\n",[130,12448,12449,12451,12453,12455,12457,12459,12461],{"class":132,"line":207},[130,12450,1012],{"class":546},[130,12452,499],{"class":162},[130,12454,11326],{"class":597},[130,12456,505],{"class":162},[130,12458,555],{"class":554},[130,12460,11285],{"class":143},[130,12462,669],{"class":180},[130,12464,12465,12467,12469,12471,12473],{"class":132,"line":224},[130,12466,5872],{"class":143},[130,12468,148],{"class":180},[130,12470,260],{"class":162},[130,12472,587],{"class":546},[130,12474,166],{"class":162},[130,12476,12477,12480,12482,12484,12486,12488],{"class":132,"line":245},[130,12478,12479],{"class":180},"  proxy",[130,12481,235],{"class":162},[130,12483,11259],{"class":180},[130,12485,235],{"class":162},[130,12487,198],{"class":143},[130,12489,669],{"class":158},[130,12491,12492,12494],{"class":132,"line":265},[130,12493,358],{"class":162},[130,12495,338],{"class":180},[130,12497,12498,12500,12502],{"class":132,"line":283},[130,12499,2193],{"class":162},[130,12501,5698],{"class":2149},[130,12503,2170],{"class":162},[16,12505,12506],{},"送信したいイベントを Proxy オブジェクトから呼べます。",[11,12508,9663],{"id":9663},[16,12510,12511],{},"今回は Nuxt Scripts の基本的な使い方について解説しました。",[16,12513,12514,12515,12517],{},"手前味噌ですが、私自身も Nuxt Scripts にコントリビュートしています。（軽微なバグ修正ですが、）",[35,12516],{},"\nまだドキュメントが整っていない部分や、改善の余地がある箇所もあるため、\nもし興味があれば、ぜひ皆さんも気軽に貢献してみてください！",[16,12519,12520],{},[2692,12521],{"alt":92,"src":12522},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1746967157/tsukiyama-blog/nuxt-scripts-introduce/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-05-11_21.37.34_ucbhoc.png",[16,12524,12525],{},"コントリビュートすると、公式ページにアイコンを掲載してもらえます。",[2420,12527,12528],{},"html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .s-3tI, html code.shiki .s-3tI{--shiki-light:#E53935;--shiki-default:#FFB757;--shiki-dark:#FFAB70}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .snYqn, html code.shiki .snYqn{--shiki-light:#E2931D;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sBxIE, html code.shiki .sBxIE{--shiki-light:#FF5370;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .s8Xov, html code.shiki .s8Xov{--shiki-light:#90A4AE;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sFHE5, html code.shiki .sFHE5{--shiki-light:#F76D47;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sDDeY, html code.shiki .sDDeY{--shiki-light:#E53935;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}",{"title":92,"searchDepth":169,"depth":169,"links":12530},[12531,12532,12535,12540,12544],{"id":2464,"depth":155,"text":2464},{"id":10610,"depth":155,"text":10611,"children":12533},[12534],{"id":10666,"depth":169,"text":10666},{"id":10687,"depth":155,"text":10688,"children":12536},[12537,12538,12539],{"id":10697,"depth":169,"text":10697},{"id":11177,"depth":169,"text":11177},{"id":11226,"depth":169,"text":11226},{"id":11238,"depth":155,"text":11239,"children":12541},[12542,12543],{"id":11254,"depth":169,"text":11254},{"id":12393,"depth":169,"text":11177},{"id":9663,"depth":155,"text":9663},"2025-05-12T00:00:00.000Z","サードパーティスクリプトの最適化・遅延読み込みなど、Nuxt.js アプリケーションにおける高度なスクリプト管理を可能にする Nuxt Modules、 Nuxt Scripts の紹介です。",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1747046645/tsukiyama-blog/nuxt-scripts-introduce/nuxt-scripts-introduce_lts8lo.webp","/tech/nuxt-scripts-introduce",{"title":10588,"description":12546},"tech/nuxt-scripts-introduce",[5256,2452,12553],"Vue.js","lBrNCBgwvKi_533yZpmb7FQU3pad8LC9A_IpHtH6L4g",{"id":12556,"title":12557,"body":12558,"date":13856,"description":13857,"extension":381,"icon":13858,"meta":13859,"navigation":419,"ogImage":13860,"path":13861,"published":419,"publishedAt":2455,"seo":13862,"stem":13863,"tags":13864,"updatedAt":2455,"__hash__":13866},"tech/tech/introduce-unhead.md","\u003Chead>管理ライブラリ Unhead の紹介",{"type":8,"value":12559,"toc":13838},[12560,12562,12568,12580,12584,12587,12600,12602,12605,12608,12613,12616,12627,12736,12742,12745,12755,12758,12764,12933,12939,12942,12952,12963,12966,13131,13137,13140,13152,13155,13158,13161,13543,13549,13777,13780,13785,13789,13809,13812,13820,13822,13824,13832,13835],[11,12561,2464],{"id":2464},[16,12563,12564,12565,12567],{},"本記事は JavaScript ツール群の UnJS の一つである Unhead について紹介する記事です。",[35,12566],{},"\n業務で触れる機会があったので備忘録がてら記事にまとめていこうと思います。",[16,12569,12570,12571,12573,12574,12576,12577,2499],{},"現代の SSR/CSR で作られる Web アプリケーションではページタイトル・メタ情報・OGP などを画面に応じて動的に変更する必要があります。",[35,12572],{},"\nこれらを毎回手動で管理するのは大変で煩雑になります。",[35,12575],{},"\nこうした課題を解決するために登場したのが、UnJS 製のヘッド管理ライブラリ",[106,12578,12579],{},"Unhead",[11,12581,12583],{"id":12582},"unhead-とは","Unhead とは？",[2523,12585],{"url":12586},"https://unhead.unjs.io/",[16,12588,12589,12590,2499,12593,12595,12596,12599],{},"Web アプリケーション向けの",[106,12591,12592],{},"フレームワークに依存しないヘッド管理ライブラリ",[35,12594],{},"\n通常、メタタグや OGP タグはテンプレートに直書きしたり、手動で状態を管理する必要がありますが、Unhead を使うと",[90,12597,12598],{},"\u003Chead>","の管理を SSR/CSR 双方に対応できます。",[11,12601,10485],{"id":10485},[16,12603,12604],{},"今回は Vue に Unhead をインストールして使ってみます。",[2523,12606],{"url":12607},"https://unhead.unjs.io/docs/vue/head/guides/get-started/installation",[76,12609,12611],{"id":12610},"usehead",[90,12612,10628],{},[2523,12614],{"url":12615},"https://unhead.unjs.io/docs/vue/head/api/composables/use-head",[16,12617,12618,12620,12621,12623,12624,12626],{},[90,12619,10628],{},"は",[90,12622,12598],{},"タグの設定を管理する型安全なリアクティブ API を提供します。",[35,12625],{},"\nまた、後に紹介する Composables でも使用される Core Composables です。",[83,12628,12630],{"className":2137,"code":12629,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nuseHead({\n  title: \"Unhead Demo\",\n  meta: [{ name: \"description\", content: \"This is a demo of Unhead!\" }],\n});\n\u003C/script>\n",[90,12631,12632,12652,12661,12677,12720,12728],{"__ignoreMap":92},[130,12633,12634,12636,12638,12640,12642,12644,12646,12648,12650],{"class":132,"line":133},[130,12635,608],{"class":162},[130,12637,5698],{"class":2149},[130,12639,2154],{"class":2153},[130,12641,2157],{"class":2153},[130,12643,2160],{"class":162},[130,12645,2163],{"class":193},[130,12647,126],{"class":197},[130,12649,2163],{"class":193},[130,12651,2170],{"class":162},[130,12653,12654,12657,12659],{"class":132,"line":155},[130,12655,12656],{"class":143},"useHead",[130,12658,148],{"class":180},[130,12660,152],{"class":162},[130,12662,12663,12666,12668,12670,12673,12675],{"class":132,"line":169},[130,12664,12665],{"class":158},"  title",[130,12667,163],{"class":162},[130,12669,11687],{"class":193},[130,12671,12672],{"class":197},"Unhead Demo",[130,12674,2163],{"class":193},[130,12676,204],{"class":162},[130,12678,12679,12682,12684,12686,12688,12691,12693,12695,12698,12700,12702,12705,12707,12709,12712,12714,12716,12718],{"class":132,"line":185},[130,12680,12681],{"class":158},"  meta",[130,12683,163],{"class":162},[130,12685,10079],{"class":180},[130,12687,2341],{"class":162},[130,12689,12690],{"class":158}," name",[130,12692,163],{"class":162},[130,12694,11687],{"class":193},[130,12696,12697],{"class":197},"description",[130,12699,2163],{"class":193},[130,12701,325],{"class":162},[130,12703,12704],{"class":158}," content",[130,12706,163],{"class":162},[130,12708,11687],{"class":193},[130,12710,12711],{"class":197},"This is a demo of Unhead!",[130,12713,2163],{"class":193},[130,12715,505],{"class":162},[130,12717,10090],{"class":180},[130,12719,204],{"class":162},[130,12721,12722,12724,12726],{"class":132,"line":207},[130,12723,358],{"class":162},[130,12725,584],{"class":180},[130,12727,10742],{"class":162},[130,12729,12730,12732,12734],{"class":132,"line":224},[130,12731,2193],{"class":162},[130,12733,5698],{"class":2149},[130,12735,2170],{"class":162},[76,12737,12739],{"id":12738},"useheadsafe",[90,12740,12741],{},"useHeadSafe()",[2523,12743],{"url":12744},"https://unhead.unjs.io/docs/vue/head/api/composables/use-head-safe",[16,12746,12747,12620,12749,12751,12752,12754],{},[90,12748,12741],{},[90,12750,10628],{},"のセキュリティに焦点を当てたラッパーです。",[35,12753],{},"\n安全な値のみを許可するように入力を制限し、信頼できないコンテンツを扱うときに XSS 攻撃からの保護を提供します。",[1576,12756,12757],{"id":12757},"ユースケース",[16,12759,12760,12761,12763],{},"例えば、ユーザーのプロフィールページでユーザの設定した文字列を",[90,12762,12598],{},"内で使用する場合があると思います。XSS攻撃のリスクがある項目を安全にフィルタリングしてくれます。",[83,12765,12767],{"className":2137,"code":12766,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nimport { useHeadSafe } from '@unhead/vue'\n\nconst profile = await useProfile(userId)\n\nuseHeadSafe({\n  title: profile.pageTitle,\n  meta: [\n    { name: 'description', content: userProfile.pageDescription },\n    ...profile.customMetaTags // これらは安全にフィルタリングされます\n  ]\n})\n\u003C/script>\n",[90,12768,12769,12789,12809,12813,12830,12834,12843,12858,12866,12898,12914,12919,12925],{"__ignoreMap":92},[130,12770,12771,12773,12775,12777,12779,12781,12783,12785,12787],{"class":132,"line":133},[130,12772,608],{"class":162},[130,12774,5698],{"class":2149},[130,12776,2154],{"class":2153},[130,12778,2157],{"class":2153},[130,12780,2160],{"class":162},[130,12782,2163],{"class":193},[130,12784,126],{"class":197},[130,12786,2163],{"class":193},[130,12788,2170],{"class":162},[130,12790,12791,12793,12795,12798,12800,12802,12804,12807],{"class":132,"line":155},[130,12792,493],{"class":136},[130,12794,499],{"class":162},[130,12796,12797],{"class":180}," useHeadSafe",[130,12799,505],{"class":162},[130,12801,508],{"class":136},[130,12803,194],{"class":193},[130,12805,12806],{"class":197},"@unhead/vue",[130,12808,515],{"class":193},[130,12810,12811],{"class":132,"line":169},[130,12812,420],{"emptyLinePlaceholder":419},[130,12814,12815,12817,12820,12822,12824,12827],{"class":132,"line":185},[130,12816,1012],{"class":546},[130,12818,12819],{"class":597}," profile",[130,12821,555],{"class":554},[130,12823,603],{"class":136},[130,12825,12826],{"class":143}," useProfile",[130,12828,12829],{"class":180},"(userId)\n",[130,12831,12832],{"class":132,"line":207},[130,12833,420],{"emptyLinePlaceholder":419},[130,12835,12836,12839,12841],{"class":132,"line":224},[130,12837,12838],{"class":143},"useHeadSafe",[130,12840,148],{"class":180},[130,12842,152],{"class":162},[130,12844,12845,12847,12849,12851,12853,12856],{"class":132,"line":245},[130,12846,12665],{"class":158},[130,12848,163],{"class":162},[130,12850,12819],{"class":180},[130,12852,235],{"class":162},[130,12854,12855],{"class":180},"pageTitle",[130,12857,204],{"class":162},[130,12859,12860,12862,12864],{"class":132,"line":265},[130,12861,12681],{"class":158},[130,12863,163],{"class":162},[130,12865,9000],{"class":180},[130,12867,12868,12871,12873,12875,12877,12879,12881,12883,12885,12887,12890,12892,12895],{"class":132,"line":283},[130,12869,12870],{"class":162},"    {",[130,12872,12690],{"class":158},[130,12874,163],{"class":162},[130,12876,194],{"class":193},[130,12878,12697],{"class":197},[130,12880,201],{"class":193},[130,12882,325],{"class":162},[130,12884,12704],{"class":158},[130,12886,163],{"class":162},[130,12888,12889],{"class":180}," userProfile",[130,12891,235],{"class":162},[130,12893,12894],{"class":180},"pageDescription ",[130,12896,12897],{"class":162},"},\n",[130,12899,12900,12903,12906,12908,12911],{"class":132,"line":302},[130,12901,12902],{"class":554},"    ...",[130,12904,12905],{"class":180},"profile",[130,12907,235],{"class":162},[130,12909,12910],{"class":180},"customMetaTags ",[130,12912,12913],{"class":328},"// これらは安全にフィルタリングされます\n",[130,12915,12916],{"class":132,"line":332},[130,12917,12918],{"class":180},"  ]\n",[130,12920,12921,12923],{"class":132,"line":341},[130,12922,358],{"class":162},[130,12924,338],{"class":180},[130,12926,12927,12929,12931],{"class":132,"line":349},[130,12928,2193],{"class":162},[130,12930,5698],{"class":2149},[130,12932,2170],{"class":162},[76,12934,12936],{"id":12935},"useseometa",[90,12937,12938],{},"useSeoMeta()",[2523,12940],{"url":12941},"https://unhead.unjs.io/docs/vue/head/api/composables/use-seo-meta",[16,12943,12944,12620,12946,12948,12949,12951],{},[90,12945,12938],{},[90,12947,10628],{},"のSEOに焦点を当てたラッパーです。",[35,12950],{},"\nTypeScriptをサポートしたフラットオブジェクトとしてメタタグを定義できます。",[16,12953,12954,12955,12958,12959,12962],{},"これにより、",[90,12956,12957],{},"property","属性の代わりに",[90,12960,12961],{},"name","を使用するようなよくある間違いを避けることができ、100以上のmetaタグが完全に型付けされているため、タイプミスを防ぐことができます。",[1576,12964,12757],{"id":12965},"ユースケース-1",[83,12967,12969],{"className":2137,"code":12968,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nimport { useSeoMeta } from '@unhead/vue'\n\nuseSeoMeta({\n  title: 'About',\n  description: 'My about page',\n  ogDescription: 'Still about my about page',\n  ogTitle: 'About',\n  ogImage: 'https://example.com/image.png',\n  twitterCard: 'summary_large_image',\n})\n\u003C/script>\n",[90,12970,12971,12991,13010,13014,13023,13038,13054,13070,13085,13101,13117,13123],{"__ignoreMap":92},[130,12972,12973,12975,12977,12979,12981,12983,12985,12987,12989],{"class":132,"line":133},[130,12974,608],{"class":162},[130,12976,5698],{"class":2149},[130,12978,2154],{"class":2153},[130,12980,2157],{"class":2153},[130,12982,2160],{"class":162},[130,12984,2163],{"class":193},[130,12986,126],{"class":197},[130,12988,2163],{"class":193},[130,12990,2170],{"class":162},[130,12992,12993,12995,12997,13000,13002,13004,13006,13008],{"class":132,"line":155},[130,12994,493],{"class":136},[130,12996,499],{"class":162},[130,12998,12999],{"class":180}," useSeoMeta",[130,13001,505],{"class":162},[130,13003,508],{"class":136},[130,13005,194],{"class":193},[130,13007,12806],{"class":197},[130,13009,515],{"class":193},[130,13011,13012],{"class":132,"line":169},[130,13013,420],{"emptyLinePlaceholder":419},[130,13015,13016,13019,13021],{"class":132,"line":185},[130,13017,13018],{"class":143},"useSeoMeta",[130,13020,148],{"class":180},[130,13022,152],{"class":162},[130,13024,13025,13027,13029,13031,13034,13036],{"class":132,"line":207},[130,13026,12665],{"class":158},[130,13028,163],{"class":162},[130,13030,194],{"class":193},[130,13032,13033],{"class":197},"About",[130,13035,201],{"class":193},[130,13037,204],{"class":162},[130,13039,13040,13043,13045,13047,13050,13052],{"class":132,"line":224},[130,13041,13042],{"class":158},"  description",[130,13044,163],{"class":162},[130,13046,194],{"class":193},[130,13048,13049],{"class":197},"My about page",[130,13051,201],{"class":193},[130,13053,204],{"class":162},[130,13055,13056,13059,13061,13063,13066,13068],{"class":132,"line":245},[130,13057,13058],{"class":158},"  ogDescription",[130,13060,163],{"class":162},[130,13062,194],{"class":193},[130,13064,13065],{"class":197},"Still about my about page",[130,13067,201],{"class":193},[130,13069,204],{"class":162},[130,13071,13072,13075,13077,13079,13081,13083],{"class":132,"line":265},[130,13073,13074],{"class":158},"  ogTitle",[130,13076,163],{"class":162},[130,13078,194],{"class":193},[130,13080,13033],{"class":197},[130,13082,201],{"class":193},[130,13084,204],{"class":162},[130,13086,13087,13090,13092,13094,13097,13099],{"class":132,"line":283},[130,13088,13089],{"class":158},"  ogImage",[130,13091,163],{"class":162},[130,13093,194],{"class":193},[130,13095,13096],{"class":197},"https://example.com/image.png",[130,13098,201],{"class":193},[130,13100,204],{"class":162},[130,13102,13103,13106,13108,13110,13113,13115],{"class":132,"line":302},[130,13104,13105],{"class":158},"  twitterCard",[130,13107,163],{"class":162},[130,13109,194],{"class":193},[130,13111,13112],{"class":197},"summary_large_image",[130,13114,201],{"class":193},[130,13116,204],{"class":162},[130,13118,13119,13121],{"class":132,"line":332},[130,13120,358],{"class":162},[130,13122,338],{"class":180},[130,13124,13125,13127,13129],{"class":132,"line":341},[130,13126,2193],{"class":162},[130,13128,5698],{"class":2149},[130,13130,2170],{"class":162},[76,13132,13134],{"id":13133},"usescript",[90,13135,13136],{},"useScript()",[2523,13138],{"url":13139},"https://unhead.unjs.io/docs/vue/head/api/composables/use-script",[16,13141,13142,13144,13145,13148,13149,13151],{},[90,13143,13136],{},"はサードパーティースクリプト（Google Analytics や 広告タグなど）を",[106,13146,13147],{},"安全かつ効率的に読み込むため","のコンポーザブルです。",[35,13150],{},"\nサードパーティースクリプトのパフォーマンス、セキュリティ、ライフサイクルを管理できます。",[16,13153,13154],{},"これにより、スクリプトがロードされる前にトラッキング処理を実行してしまうミスや、同一スクリプトを重複して読み込んでしまうパフォーマンス上の問題を防ぐことができます。",[1576,13156,12757],{"id":13157},"ユースケース-2",[16,13159,13160],{},"このようなサードパーティのスクリプトがあるとします",[83,13162,13167],{"className":13163,"code":13164,"filename":13165,"language":13166,"meta":92,"style":92},"language-js shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","(function (globalName) {\n  if (!window[globalName]) {\n    const queue = []\n    const api = function (...args) {\n      queue.push(args)\n    }\n\n    api._queue = queue\n    api._ready = false\n    api.init = function () {\n      api._ready = true\n      console.log(`[${globalName}] initialized`)\n      console.log(`[${globalName}] queued calls:`, queue)\n    }\n    api.track = function (eventName, payload) {\n      if (!api._ready) {\n        return queue.push(['track', eventName, payload])\n      }\n      console.log(`[${globalName}] Tracking:`, eventName, payload)\n    }\n\n    window[globalName] = api\n  }\n})('myScript')\n","myScript.js","js",[90,13168,13169,13184,13203,13215,13239,13254,13258,13262,13277,13290,13307,13320,13349,13380,13384,13410,13429,13459,13463,13498,13502,13506,13523,13527],{"__ignoreMap":92},[130,13170,13171,13173,13175,13177,13180,13182],{"class":132,"line":133},[130,13172,148],{"class":180},[130,13174,11491],{"class":546},[130,13176,561],{"class":162},[130,13178,13179],{"class":564},"globalName",[130,13181,584],{"class":162},[130,13183,166],{"class":162},[130,13185,13186,13188,13190,13192,13194,13196,13198,13201],{"class":132,"line":155},[130,13187,1159],{"class":136},[130,13189,561],{"class":158},[130,13191,1432],{"class":554},[130,13193,12331],{"class":180},[130,13195,11535],{"class":158},[130,13197,13179],{"class":180},[130,13199,13200],{"class":158},"]) ",[130,13202,152],{"class":162},[130,13204,13205,13207,13210,13212],{"class":132,"line":169},[130,13206,5949],{"class":546},[130,13208,13209],{"class":597}," queue",[130,13211,555],{"class":554},[130,13213,13214],{"class":158}," []\n",[130,13216,13217,13219,13222,13224,13227,13229,13232,13235,13237],{"class":132,"line":185},[130,13218,5949],{"class":546},[130,13220,13221],{"class":550}," api",[130,13223,555],{"class":554},[130,13225,13226],{"class":546}," function",[130,13228,561],{"class":162},[130,13230,13231],{"class":554},"...",[130,13233,13234],{"class":564},"args",[130,13236,584],{"class":162},[130,13238,166],{"class":162},[130,13240,13241,13244,13246,13248,13250,13252],{"class":132,"line":207},[130,13242,13243],{"class":180},"      queue",[130,13245,235],{"class":162},[130,13247,11759],{"class":143},[130,13249,148],{"class":158},[130,13251,13234],{"class":180},[130,13253,338],{"class":158},[130,13255,13256],{"class":132,"line":224},[130,13257,2105],{"class":162},[130,13259,13260],{"class":132,"line":245},[130,13261,420],{"emptyLinePlaceholder":419},[130,13263,13264,13267,13269,13272,13274],{"class":132,"line":265},[130,13265,13266],{"class":180},"    api",[130,13268,235],{"class":162},[130,13270,13271],{"class":180},"_queue",[130,13273,555],{"class":554},[130,13275,13276],{"class":180}," queue\n",[130,13278,13279,13281,13283,13286,13288],{"class":132,"line":283},[130,13280,13266],{"class":180},[130,13282,235],{"class":162},[130,13284,13285],{"class":180},"_ready",[130,13287,555],{"class":554},[130,13289,9992],{"class":1450},[130,13291,13292,13294,13296,13299,13301,13303,13305],{"class":132,"line":302},[130,13293,13266],{"class":180},[130,13295,235],{"class":162},[130,13297,13298],{"class":143},"init",[130,13300,555],{"class":554},[130,13302,13226],{"class":546},[130,13304,1912],{"class":162},[130,13306,166],{"class":162},[130,13308,13309,13312,13314,13316,13318],{"class":132,"line":332},[130,13310,13311],{"class":180},"      api",[130,13313,235],{"class":162},[130,13315,13285],{"class":180},[130,13317,555],{"class":554},[130,13319,1451],{"class":1450},[130,13321,13322,13325,13327,13330,13332,13334,13336,13338,13340,13342,13345,13347],{"class":132,"line":341},[130,13323,13324],{"class":180},"      console",[130,13326,235],{"class":162},[130,13328,13329],{"class":143},"log",[130,13331,148],{"class":158},[130,13333,645],{"class":193},[130,13335,11535],{"class":197},[130,13337,651],{"class":193},[130,13339,13179],{"class":180},[130,13341,358],{"class":193},[130,13343,13344],{"class":197},"] initialized",[130,13346,645],{"class":193},[130,13348,338],{"class":158},[130,13350,13351,13353,13355,13357,13359,13361,13363,13365,13367,13369,13372,13374,13376,13378],{"class":132,"line":349},[130,13352,13324],{"class":180},[130,13354,235],{"class":162},[130,13356,13329],{"class":143},[130,13358,148],{"class":158},[130,13360,645],{"class":193},[130,13362,11535],{"class":197},[130,13364,651],{"class":193},[130,13366,13179],{"class":180},[130,13368,358],{"class":193},[130,13370,13371],{"class":197},"] queued calls:",[130,13373,645],{"class":193},[130,13375,325],{"class":162},[130,13377,13209],{"class":180},[130,13379,338],{"class":158},[130,13381,13382],{"class":132,"line":355},[130,13383,2105],{"class":162},[130,13385,13386,13388,13390,13392,13394,13396,13398,13401,13403,13406,13408],{"class":132,"line":783},[130,13387,13266],{"class":180},[130,13389,235],{"class":162},[130,13391,11581],{"class":143},[130,13393,555],{"class":554},[130,13395,13226],{"class":546},[130,13397,561],{"class":162},[130,13399,13400],{"class":564},"eventName",[130,13402,325],{"class":162},[130,13404,13405],{"class":564}," payload",[130,13407,584],{"class":162},[130,13409,166],{"class":162},[130,13411,13412,13414,13416,13418,13421,13423,13425,13427],{"class":132,"line":793},[130,13413,7700],{"class":136},[130,13415,561],{"class":158},[130,13417,1432],{"class":554},[130,13419,13420],{"class":180},"api",[130,13422,235],{"class":162},[130,13424,13285],{"class":180},[130,13426,1174],{"class":158},[130,13428,152],{"class":162},[130,13430,13431,13433,13435,13437,13439,13441,13443,13445,13447,13449,13452,13454,13456],{"class":132,"line":798},[130,13432,11431],{"class":136},[130,13434,13209],{"class":180},[130,13436,235],{"class":162},[130,13438,11759],{"class":143},[130,13440,11762],{"class":158},[130,13442,201],{"class":193},[130,13444,11581],{"class":197},[130,13446,201],{"class":193},[130,13448,325],{"class":162},[130,13450,13451],{"class":180}," eventName",[130,13453,325],{"class":162},[130,13455,13405],{"class":180},[130,13457,13458],{"class":158},"])\n",[130,13460,13461],{"class":132,"line":806},[130,13462,7739],{"class":162},[130,13464,13465,13467,13469,13471,13473,13475,13477,13479,13481,13483,13486,13488,13490,13492,13494,13496],{"class":132,"line":1073},[130,13466,13324],{"class":180},[130,13468,235],{"class":162},[130,13470,13329],{"class":143},[130,13472,148],{"class":158},[130,13474,645],{"class":193},[130,13476,11535],{"class":197},[130,13478,651],{"class":193},[130,13480,13179],{"class":180},[130,13482,358],{"class":193},[130,13484,13485],{"class":197},"] Tracking:",[130,13487,645],{"class":193},[130,13489,325],{"class":162},[130,13491,13451],{"class":180},[130,13493,325],{"class":162},[130,13495,13405],{"class":180},[130,13497,338],{"class":158},[130,13499,13500],{"class":132,"line":1086},[130,13501,2105],{"class":162},[130,13503,13504],{"class":132,"line":1092},[130,13505,420],{"emptyLinePlaceholder":419},[130,13507,13508,13511,13513,13515,13518,13520],{"class":132,"line":1128},[130,13509,13510],{"class":180},"    window",[130,13512,11535],{"class":158},[130,13514,13179],{"class":180},[130,13516,13517],{"class":158},"] ",[130,13519,2160],{"class":554},[130,13521,13522],{"class":180}," api\n",[130,13524,13525],{"class":132,"line":1151},[130,13526,352],{"class":162},[130,13528,13529,13531,13534,13536,13539,13541],{"class":132,"line":1156},[130,13530,358],{"class":162},[130,13532,13533],{"class":180},")(",[130,13535,201],{"class":193},[130,13537,13538],{"class":197},"myScript",[130,13540,201],{"class":193},[130,13542,338],{"class":180},[16,13544,13545,13546,13548],{},"よくあるスクリプトです。初期化処理とトラックイベントが用意されています。",[35,13547],{},"\n今回は動作確認のために、初期化処理やトラッキング時に console.log() を出力するようにしています。",[83,13550,13552],{"className":2137,"code":13551,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nimport { useScript } from '@unhead/vue'\n\nconst { onLoaded } = useScript('/scripts/myscript.js', {\n  trigger: 'client',\n  use: () => window.myScript,\n})\n\n// スクリプトロード後に初期化＆イベントを送る\nonLoaded((api) => {\n  console.log('myscript loaded:', api)\n  api.init()\n  api.track('pageview', { url: '/' })\n})\n\u003C/script>\n",[90,13553,13554,13574,13593,13597,13624,13640,13659,13665,13669,13674,13691,13715,13726,13763,13769],{"__ignoreMap":92},[130,13555,13556,13558,13560,13562,13564,13566,13568,13570,13572],{"class":132,"line":133},[130,13557,608],{"class":162},[130,13559,5698],{"class":2149},[130,13561,2154],{"class":2153},[130,13563,2157],{"class":2153},[130,13565,2160],{"class":162},[130,13567,2163],{"class":193},[130,13569,126],{"class":197},[130,13571,2163],{"class":193},[130,13573,2170],{"class":162},[130,13575,13576,13578,13580,13583,13585,13587,13589,13591],{"class":132,"line":155},[130,13577,493],{"class":136},[130,13579,499],{"class":162},[130,13581,13582],{"class":180}," useScript",[130,13584,505],{"class":162},[130,13586,508],{"class":136},[130,13588,194],{"class":193},[130,13590,12806],{"class":197},[130,13592,515],{"class":193},[130,13594,13595],{"class":132,"line":169},[130,13596,420],{"emptyLinePlaceholder":419},[130,13598,13599,13601,13603,13605,13607,13609,13611,13613,13615,13618,13620,13622],{"class":132,"line":185},[130,13600,1012],{"class":546},[130,13602,499],{"class":162},[130,13604,5854],{"class":597},[130,13606,505],{"class":162},[130,13608,555],{"class":554},[130,13610,13582],{"class":143},[130,13612,148],{"class":180},[130,13614,201],{"class":193},[130,13616,13617],{"class":197},"/scripts/myscript.js",[130,13619,201],{"class":193},[130,13621,325],{"class":162},[130,13623,166],{"class":162},[130,13625,13626,13629,13631,13633,13636,13638],{"class":132,"line":207},[130,13627,13628],{"class":158},"  trigger",[130,13630,163],{"class":162},[130,13632,194],{"class":193},[130,13634,13635],{"class":197},"client",[130,13637,201],{"class":193},[130,13639,204],{"class":162},[130,13641,13642,13645,13647,13649,13651,13653,13655,13657],{"class":132,"line":224},[130,13643,13644],{"class":143},"  use",[130,13646,163],{"class":162},[130,13648,1912],{"class":162},[130,13650,587],{"class":546},[130,13652,11441],{"class":180},[130,13654,235],{"class":162},[130,13656,13538],{"class":180},[130,13658,204],{"class":162},[130,13660,13661,13663],{"class":132,"line":245},[130,13662,358],{"class":162},[130,13664,338],{"class":180},[130,13666,13667],{"class":132,"line":265},[130,13668,420],{"emptyLinePlaceholder":419},[130,13670,13671],{"class":132,"line":283},[130,13672,13673],{"class":328},"// スクリプトロード後に初期化＆イベントを送る\n",[130,13675,13676,13679,13681,13683,13685,13687,13689],{"class":132,"line":302},[130,13677,13678],{"class":143},"onLoaded",[130,13680,148],{"class":180},[130,13682,148],{"class":162},[130,13684,13420],{"class":564},[130,13686,584],{"class":162},[130,13688,587],{"class":546},[130,13690,166],{"class":162},[130,13692,13693,13696,13698,13700,13702,13704,13707,13709,13711,13713],{"class":132,"line":332},[130,13694,13695],{"class":180},"  console",[130,13697,235],{"class":162},[130,13699,13329],{"class":143},[130,13701,148],{"class":158},[130,13703,201],{"class":193},[130,13705,13706],{"class":197},"myscript loaded:",[130,13708,201],{"class":193},[130,13710,325],{"class":162},[130,13712,13221],{"class":180},[130,13714,338],{"class":158},[130,13716,13717,13720,13722,13724],{"class":132,"line":341},[130,13718,13719],{"class":180},"  api",[130,13721,235],{"class":162},[130,13723,13298],{"class":143},[130,13725,669],{"class":158},[130,13727,13728,13730,13732,13734,13736,13738,13741,13743,13745,13747,13750,13752,13754,13757,13759,13761],{"class":132,"line":349},[130,13729,13719],{"class":180},[130,13731,235],{"class":162},[130,13733,11581],{"class":143},[130,13735,148],{"class":158},[130,13737,201],{"class":193},[130,13739,13740],{"class":197},"pageview",[130,13742,201],{"class":193},[130,13744,325],{"class":162},[130,13746,499],{"class":162},[130,13748,13749],{"class":158}," url",[130,13751,163],{"class":162},[130,13753,194],{"class":193},[130,13755,13756],{"class":197},"/",[130,13758,201],{"class":193},[130,13760,505],{"class":162},[130,13762,338],{"class":158},[130,13764,13765,13767],{"class":132,"line":355},[130,13766,358],{"class":162},[130,13768,338],{"class":180},[130,13770,13771,13773,13775],{"class":132,"line":783},[130,13772,2193],{"class":162},[130,13774,5698],{"class":2149},[130,13776,2170],{"class":162},[16,13778,13779],{},"Consoleを確認するとイベントが発火していることがわかります。",[16,13781,13782],{},[2692,13783],{"alt":92,"src":13784},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1746431984/tsukiyama-blog/introduce-unhead/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-05-05_16.58.47_et58l8.png",[11,13786,13788],{"id":13787},"nuxt-ではどうなのか","Nuxt ではどうなのか？",[16,13790,13791,13792,13794,13795,13797,13798,13800,13801,13804,13805,13808],{},"Unhead は Nuxt 3 でもデフォルトで採用されており、",[90,13793,10628],{}," や ",[90,13796,12938],{}," は追加インストールなしでそのまま使えます。",[35,13799],{},"\n(",[90,13802,13803],{},"nuxt v3.16","からは",[90,13806,13807],{},"unhead v2","がデフォルトでサポートされています)",[2523,13810],{"url":13811},"https://nuxt.com/blog/v3-16",[16,13813,13814,13816,13817,13819],{},[90,13815,13136],{},"は Nuxt 3 にデフォルトでは含まれていません。",[35,13818],{},"\nNuxt Scripts を追加でインストールすることで使用できます。",[2523,13821],{"url":5376},[11,13823,9663],{"id":9663},[16,13825,13826,13827,13829,13831],{},"今回は、Unhead の基本的な使い方と主要な Composables について紹介しました。",[35,13828],{},[90,13830,12598],{},"の管理は少しの設定ミスでページスピードが遅くなったりセキュリティ上の脅威になるので適切に設定していきたいですね。",[16,13833,13834],{},"次回は、Nuxt Modules の Nuxt Scripts についても紹介したいと思います。",[2420,13836,13837],{},"html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .s8Xov, html code.shiki .s8Xov{--shiki-light:#90A4AE;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sBxIE, html code.shiki .sBxIE{--shiki-light:#FF5370;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}",{"title":92,"searchDepth":169,"depth":169,"links":13839},[13840,13841,13842,13854,13855],{"id":2464,"depth":155,"text":2464},{"id":12582,"depth":155,"text":12583},{"id":10485,"depth":155,"text":10485,"children":13843},[13844,13845,13848,13851],{"id":12610,"depth":169,"text":10628},{"id":12738,"depth":169,"text":12741,"children":13846},[13847],{"id":12757,"depth":185,"text":12757},{"id":12935,"depth":169,"text":12938,"children":13849},[13850],{"id":12965,"depth":185,"text":12757},{"id":13133,"depth":169,"text":13136,"children":13852},[13853],{"id":13157,"depth":185,"text":12757},{"id":13787,"depth":155,"text":13788},{"id":9663,"depth":155,"text":9663},"2025-05-05T00:00:00.000Z","フレームワーク非依存\u003Chead>管理ライブラリのUnheadの紹介です。","/avatar_bwg8e2.webp",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1746433649/tsukiyama-blog/introduce-unhead/Frame_6_pwvdwd.png","/tech/introduce-unhead",{"title":12557,"description":13857},"tech/introduce-unhead",[5256,13865],"UnJs","aDEaGZN8D9dTVyTTp9fKxBwqkygsoGGZIFfniYrJoFw",{"id":13868,"title":13869,"body":13870,"date":14644,"description":14645,"extension":381,"icon":13858,"meta":14646,"navigation":419,"ogImage":14647,"path":14648,"published":419,"publishedAt":2455,"seo":14649,"stem":14650,"tags":14651,"updatedAt":2455,"__hash__":14653},"tech/tech/geolocation-api.md","デバイスの位置情報を取得する Geolocation API の紹介",{"type":8,"value":13871,"toc":14635},[13872,13874,13877,13880,13886,13889,14025,14031,14034,14046,14228,14240,14243,14377,14615,14618,14624,14626,14632],[11,13873,2464],{"id":2464},[16,13875,13876],{},"Web で位置情報を簡単に扱える Geolocation API を紹介します。",[2523,13878],{"url":13879},"https://developer.mozilla.org/ja/docs/Web/API/Geolocation_API",[16,13881,13882,13883,13885],{},"Geolocation API は Web 標準のAPIで、ユーザーの位置情報（緯度・経度）の取得ができます。",[35,13884],{},"\n利用にはユーザ許可が必要です。",[11,13887,13888],{"id":13888},"基本的な使い方",[83,13890,13892],{"className":123,"code":13891,"language":126,"meta":92,"style":92},"// 位置情報を取得する\nnavigator.geolocation.getCurrentPosition(\n  (position) => {\n    console.log(`緯度：${position.coords.latitude}`, `経度：${position.coords.longitude}`)\n  },\n  (error) => {\n    console.error(error)\n  }\n)\n",[90,13893,13894,13899,13916,13929,13985,13990,14003,14017,14021],{"__ignoreMap":92},[130,13895,13896],{"class":132,"line":133},[130,13897,13898],{"class":328},"// 位置情報を取得する\n",[130,13900,13901,13904,13906,13909,13911,13914],{"class":132,"line":155},[130,13902,13903],{"class":180},"navigator",[130,13905,235],{"class":162},[130,13907,13908],{"class":180},"geolocation",[130,13910,235],{"class":162},[130,13912,13913],{"class":143},"getCurrentPosition",[130,13915,1507],{"class":180},[130,13917,13918,13921,13923,13925,13927],{"class":132,"line":169},[130,13919,13920],{"class":162},"  (",[130,13922,6059],{"class":564},[130,13924,584],{"class":162},[130,13926,587],{"class":546},[130,13928,166],{"class":162},[130,13930,13931,13934,13936,13938,13940,13942,13945,13947,13949,13951,13954,13956,13959,13961,13963,13965,13968,13970,13972,13974,13976,13978,13981,13983],{"class":132,"line":185},[130,13932,13933],{"class":180},"    console",[130,13935,235],{"class":162},[130,13937,13329],{"class":143},[130,13939,148],{"class":158},[130,13941,645],{"class":193},[130,13943,13944],{"class":197},"緯度：",[130,13946,651],{"class":193},[130,13948,6059],{"class":180},[130,13950,235],{"class":193},[130,13952,13953],{"class":180},"coords",[130,13955,235],{"class":193},[130,13957,13958],{"class":180},"latitude",[130,13960,657],{"class":193},[130,13962,325],{"class":162},[130,13964,11374],{"class":193},[130,13966,13967],{"class":197},"経度：",[130,13969,651],{"class":193},[130,13971,6059],{"class":180},[130,13973,235],{"class":193},[130,13975,13953],{"class":180},[130,13977,235],{"class":193},[130,13979,13980],{"class":180},"longitude",[130,13982,657],{"class":193},[130,13984,338],{"class":158},[130,13986,13987],{"class":132,"line":207},[130,13988,13989],{"class":162},"  },\n",[130,13991,13992,13994,13997,13999,14001],{"class":132,"line":224},[130,13993,13920],{"class":162},[130,13995,13996],{"class":564},"error",[130,13998,584],{"class":162},[130,14000,587],{"class":546},[130,14002,166],{"class":162},[130,14004,14005,14007,14009,14011,14013,14015],{"class":132,"line":245},[130,14006,13933],{"class":180},[130,14008,235],{"class":162},[130,14010,13996],{"class":143},[130,14012,148],{"class":158},[130,14014,13996],{"class":180},[130,14016,338],{"class":158},[130,14018,14019],{"class":132,"line":265},[130,14020,352],{"class":162},[130,14022,14023],{"class":132,"line":283},[130,14024,338],{"class":180},[16,14026,14027,14028,14030],{},"Web 標準のAPIなので何かをインストールすることなく使用できます。",[35,14029],{},"\nブラウザで確認するとユーザー許可のダイアログが展開されます。\n許可すると位置情報の取得ができます。",[11,14032,14033],{"id":14033},"継続的に位置を取得する方法",[16,14035,14036,14039,14040,14042,14043,5373],{},[90,14037,14038],{},"getCurrentPosition()"," は位置情報を一度だけ取得するメソッドでした。",[35,14041],{},"\n継続的に取得するためには ",[90,14044,14045],{},"watchPosition()",[83,14047,14049],{"className":123,"code":14048,"language":126,"meta":92,"style":92},"// 位置情報を監視する\nconst watchID = navigator.geolocation.watchPosition(\n  (position) => {\n    console.log(`緯度：${position.coords.latitude}`, `経度：${position.coords.longitude}`)\n  },\n  (error) => {\n    console.error(error)\n  }\n)\n\n// 位置情報の監視を終了する\nconst clear = () => {\n  navigator.geolocation.clearWatch(watchID)\n}\n",[90,14050,14051,14056,14079,14091,14141,14145,14157,14171,14175,14179,14183,14188,14203,14224],{"__ignoreMap":92},[130,14052,14053],{"class":132,"line":133},[130,14054,14055],{"class":328},"// 位置情報を監視する\n",[130,14057,14058,14060,14063,14065,14068,14070,14072,14074,14077],{"class":132,"line":155},[130,14059,1012],{"class":546},[130,14061,14062],{"class":597}," watchID",[130,14064,555],{"class":554},[130,14066,14067],{"class":180}," navigator",[130,14069,235],{"class":162},[130,14071,13908],{"class":180},[130,14073,235],{"class":162},[130,14075,14076],{"class":143},"watchPosition",[130,14078,1507],{"class":180},[130,14080,14081,14083,14085,14087,14089],{"class":132,"line":169},[130,14082,13920],{"class":162},[130,14084,6059],{"class":564},[130,14086,584],{"class":162},[130,14088,587],{"class":546},[130,14090,166],{"class":162},[130,14092,14093,14095,14097,14099,14101,14103,14105,14107,14109,14111,14113,14115,14117,14119,14121,14123,14125,14127,14129,14131,14133,14135,14137,14139],{"class":132,"line":185},[130,14094,13933],{"class":180},[130,14096,235],{"class":162},[130,14098,13329],{"class":143},[130,14100,148],{"class":158},[130,14102,645],{"class":193},[130,14104,13944],{"class":197},[130,14106,651],{"class":193},[130,14108,6059],{"class":180},[130,14110,235],{"class":193},[130,14112,13953],{"class":180},[130,14114,235],{"class":193},[130,14116,13958],{"class":180},[130,14118,657],{"class":193},[130,14120,325],{"class":162},[130,14122,11374],{"class":193},[130,14124,13967],{"class":197},[130,14126,651],{"class":193},[130,14128,6059],{"class":180},[130,14130,235],{"class":193},[130,14132,13953],{"class":180},[130,14134,235],{"class":193},[130,14136,13980],{"class":180},[130,14138,657],{"class":193},[130,14140,338],{"class":158},[130,14142,14143],{"class":132,"line":207},[130,14144,13989],{"class":162},[130,14146,14147,14149,14151,14153,14155],{"class":132,"line":224},[130,14148,13920],{"class":162},[130,14150,13996],{"class":564},[130,14152,584],{"class":162},[130,14154,587],{"class":546},[130,14156,166],{"class":162},[130,14158,14159,14161,14163,14165,14167,14169],{"class":132,"line":245},[130,14160,13933],{"class":180},[130,14162,235],{"class":162},[130,14164,13996],{"class":143},[130,14166,148],{"class":158},[130,14168,13996],{"class":180},[130,14170,338],{"class":158},[130,14172,14173],{"class":132,"line":265},[130,14174,352],{"class":162},[130,14176,14177],{"class":132,"line":283},[130,14178,338],{"class":180},[130,14180,14181],{"class":132,"line":302},[130,14182,420],{"emptyLinePlaceholder":419},[130,14184,14185],{"class":132,"line":332},[130,14186,14187],{"class":328},"// 位置情報の監視を終了する\n",[130,14189,14190,14192,14195,14197,14199,14201],{"class":132,"line":341},[130,14191,1012],{"class":546},[130,14193,14194],{"class":550}," clear",[130,14196,555],{"class":554},[130,14198,1912],{"class":162},[130,14200,587],{"class":546},[130,14202,166],{"class":162},[130,14204,14205,14208,14210,14212,14214,14217,14219,14222],{"class":132,"line":349},[130,14206,14207],{"class":180},"  navigator",[130,14209,235],{"class":162},[130,14211,13908],{"class":180},[130,14213,235],{"class":162},[130,14215,14216],{"class":143},"clearWatch",[130,14218,148],{"class":158},[130,14220,14221],{"class":180},"watchID",[130,14223,338],{"class":158},[130,14225,14226],{"class":132,"line":355},[130,14227,686],{"class":162},[16,14229,14230,14232,14233,14235,14236,14239],{},[90,14231,14045],{}," は位置情報を識別するIDを返します。",[35,14234],{},"\n監視を終了するには、",[90,14237,14238],{},"clearWatch()"," に ID を渡します。",[11,14241,14242],{"id":14242},"実装例",[83,14244,14247],{"className":123,"code":14245,"filename":14246,"language":126,"meta":92,"style":92},"export const useGeoLocation = () => {\n  const position = ref\u003CGeolocationPosition | null>(null)\n  const getPosition = () => {\n    navigator.geolocation.getCurrentPosition((pos) => {\n      position.value = pos\n    })\n  }\n  return { position, getPosition }\n}\n\n","geo-location.ts",[90,14248,14249,14266,14294,14309,14335,14349,14355,14359,14373],{"__ignoreMap":92},[130,14250,14251,14253,14255,14258,14260,14262,14264],{"class":132,"line":133},[130,14252,137],{"class":136},[130,14254,547],{"class":546},[130,14256,14257],{"class":550}," useGeoLocation",[130,14259,555],{"class":554},[130,14261,1912],{"class":162},[130,14263,587],{"class":546},[130,14265,166],{"class":162},[130,14267,14268,14270,14273,14275,14277,14279,14282,14284,14286,14288,14290,14292],{"class":132,"line":155},[130,14269,594],{"class":546},[130,14271,14272],{"class":597}," position",[130,14274,555],{"class":554},[130,14276,5823],{"class":143},[130,14278,608],{"class":162},[130,14280,14281],{"class":570},"GeolocationPosition",[130,14283,2061],{"class":554},[130,14285,1171],{"class":580},[130,14287,618],{"class":162},[130,14289,148],{"class":158},[130,14291,5839],{"class":1170},[130,14293,338],{"class":158},[130,14295,14296,14298,14301,14303,14305,14307],{"class":132,"line":169},[130,14297,594],{"class":546},[130,14299,14300],{"class":550}," getPosition",[130,14302,555],{"class":554},[130,14304,1912],{"class":162},[130,14306,587],{"class":546},[130,14308,166],{"class":162},[130,14310,14311,14314,14316,14318,14320,14322,14324,14326,14329,14331,14333],{"class":132,"line":185},[130,14312,14313],{"class":180},"    navigator",[130,14315,235],{"class":162},[130,14317,13908],{"class":180},[130,14319,235],{"class":162},[130,14321,13913],{"class":143},[130,14323,148],{"class":158},[130,14325,148],{"class":162},[130,14327,14328],{"class":564},"pos",[130,14330,584],{"class":162},[130,14332,587],{"class":546},[130,14334,166],{"class":162},[130,14336,14337,14340,14342,14344,14346],{"class":132,"line":207},[130,14338,14339],{"class":180},"      position",[130,14341,235],{"class":162},[130,14343,5922],{"class":180},[130,14345,555],{"class":554},[130,14347,14348],{"class":180}," pos\n",[130,14350,14351,14353],{"class":132,"line":224},[130,14352,344],{"class":162},[130,14354,338],{"class":158},[130,14356,14357],{"class":132,"line":245},[130,14358,352],{"class":162},[130,14360,14361,14363,14365,14367,14369,14371],{"class":132,"line":265},[130,14362,678],{"class":136},[130,14364,499],{"class":162},[130,14366,14272],{"class":180},[130,14368,325],{"class":162},[130,14370,14300],{"class":180},[130,14372,1998],{"class":162},[130,14374,14375],{"class":132,"line":283},[130,14376,686],{"class":162},[83,14378,14381],{"className":2137,"code":14379,"filename":14380,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nimport { useGeoLocation } from '~/composables/articles/geolocation-api'\n\nconst { position, getPosition } = useGeoLocation()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"space-y-2\">\n    \u003Cul class=\"space-y-2\">\n      \u003Cli>緯度：{{ position?.coords.latitude }}\u003C/li>\n      \u003Cli>軽度：{{ position?.coords.longitude }}\u003C/li>\n    \u003C/ul>\n    \u003Cbutton\n      class=\"bg-blue-600 w-fit block mx-auto text-white rounded-sm py-1 px-2 cursor-pointer\"\n      @click=\"getPosition\"\n    >\n      位置情報を取得する\n    \u003C/button>\n  \u003C/div>\n\u003C/template>\n","GeoLocation.vue",[90,14382,14383,14403,14422,14426,14446,14454,14458,14466,14485,14503,14520,14537,14545,14552,14566,14580,14585,14590,14599,14607],{"__ignoreMap":92},[130,14384,14385,14387,14389,14391,14393,14395,14397,14399,14401],{"class":132,"line":133},[130,14386,608],{"class":162},[130,14388,5698],{"class":2149},[130,14390,2154],{"class":2153},[130,14392,2157],{"class":2153},[130,14394,2160],{"class":162},[130,14396,2163],{"class":193},[130,14398,126],{"class":197},[130,14400,2163],{"class":193},[130,14402,2170],{"class":162},[130,14404,14405,14407,14409,14411,14413,14415,14417,14420],{"class":132,"line":155},[130,14406,493],{"class":136},[130,14408,499],{"class":162},[130,14410,14257],{"class":180},[130,14412,505],{"class":162},[130,14414,508],{"class":136},[130,14416,194],{"class":193},[130,14418,14419],{"class":197},"~/composables/articles/geolocation-api",[130,14421,515],{"class":193},[130,14423,14424],{"class":132,"line":169},[130,14425,420],{"emptyLinePlaceholder":419},[130,14427,14428,14430,14432,14434,14436,14438,14440,14442,14444],{"class":132,"line":185},[130,14429,1012],{"class":546},[130,14431,499],{"class":162},[130,14433,14272],{"class":597},[130,14435,325],{"class":162},[130,14437,14300],{"class":597},[130,14439,505],{"class":162},[130,14441,555],{"class":554},[130,14443,14257],{"class":143},[130,14445,669],{"class":180},[130,14447,14448,14450,14452],{"class":132,"line":207},[130,14449,2193],{"class":162},[130,14451,5698],{"class":2149},[130,14453,2170],{"class":162},[130,14455,14456],{"class":132,"line":224},[130,14457,420],{"emptyLinePlaceholder":419},[130,14459,14460,14462,14464],{"class":132,"line":245},[130,14461,608],{"class":162},[130,14463,2130],{"class":2149},[130,14465,2170],{"class":162},[130,14467,14468,14470,14472,14474,14476,14478,14481,14483],{"class":132,"line":265},[130,14469,2989],{"class":162},[130,14471,2683],{"class":2149},[130,14473,2973],{"class":2153},[130,14475,2160],{"class":162},[130,14477,2163],{"class":193},[130,14479,14480],{"class":197},"space-y-2",[130,14482,2163],{"class":193},[130,14484,2170],{"class":162},[130,14486,14487,14489,14491,14493,14495,14497,14499,14501],{"class":132,"line":283},[130,14488,3010],{"class":162},[130,14490,2566],{"class":2149},[130,14492,2973],{"class":2153},[130,14494,2160],{"class":162},[130,14496,2163],{"class":193},[130,14498,14480],{"class":197},[130,14500,2163],{"class":193},[130,14502,2170],{"class":162},[130,14504,14505,14507,14509,14511,14514,14516,14518],{"class":132,"line":302},[130,14506,3030],{"class":162},[130,14508,2569],{"class":2149},[130,14510,618],{"class":162},[130,14512,14513],{"class":180},"緯度：{{ position?.coords.latitude }}",[130,14515,2193],{"class":162},[130,14517,2569],{"class":2149},[130,14519,2170],{"class":162},[130,14521,14522,14524,14526,14528,14531,14533,14535],{"class":132,"line":332},[130,14523,3030],{"class":162},[130,14525,2569],{"class":2149},[130,14527,618],{"class":162},[130,14529,14530],{"class":180},"軽度：{{ position?.coords.longitude }}",[130,14532,2193],{"class":162},[130,14534,2569],{"class":2149},[130,14536,2170],{"class":162},[130,14538,14539,14541,14543],{"class":132,"line":341},[130,14540,3042],{"class":162},[130,14542,2566],{"class":2149},[130,14544,2170],{"class":162},[130,14546,14547,14549],{"class":132,"line":349},[130,14548,3010],{"class":162},[130,14550,14551],{"class":2149},"button\n",[130,14553,14554,14557,14559,14561,14564],{"class":132,"line":355},[130,14555,14556],{"class":2153},"      class",[130,14558,2160],{"class":162},[130,14560,2163],{"class":193},[130,14562,14563],{"class":197},"bg-blue-600 w-fit block mx-auto text-white rounded-sm py-1 px-2 cursor-pointer",[130,14565,2789],{"class":193},[130,14567,14568,14571,14573,14575,14578],{"class":132,"line":783},[130,14569,14570],{"class":2153},"      @click",[130,14572,2160],{"class":162},[130,14574,2163],{"class":193},[130,14576,14577],{"class":197},"getPosition",[130,14579,2789],{"class":193},[130,14581,14582],{"class":132,"line":793},[130,14583,14584],{"class":162},"    >\n",[130,14586,14587],{"class":132,"line":798},[130,14588,14589],{"class":180},"      位置情報を取得する\n",[130,14591,14592,14594,14597],{"class":132,"line":806},[130,14593,3042],{"class":162},[130,14595,14596],{"class":2149},"button",[130,14598,2170],{"class":162},[130,14600,14601,14603,14605],{"class":132,"line":1073},[130,14602,3051],{"class":162},[130,14604,2683],{"class":2149},[130,14606,2170],{"class":162},[130,14608,14609,14611,14613],{"class":132,"line":1086},[130,14610,2193],{"class":162},[130,14612,2130],{"class":2149},[130,14614,2170],{"class":162},[76,14616,14617],{"id":14617},"動かしてみる",[14619,14620,14621],"demo-browser",{},[14622,14623],"geo-location",{},[11,14625,9663],{"id":9663},[16,14627,14628,14629,14631],{},"今回は Geolocation API を使ってブラウザで位置情報を扱う方法についてまとめました。",[35,14630],{},"\n位置情報を使って作ってみたいものがあるので機会があれば記事にしようと思います。",[2420,14633,14634],{},"html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .s8Xov, html code.shiki .s8Xov{--shiki-light:#90A4AE;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sywW5, html code.shiki .sywW5{--shiki-light:#E2931D;--shiki-default:#FFB757;--shiki-dark:#B392F0}html pre.shiki code .snYqn, html code.shiki .snYqn{--shiki-light:#E2931D;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .s4Pz2, html code.shiki .s4Pz2{--shiki-light:#39ADB5;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}",{"title":92,"searchDepth":169,"depth":169,"links":14636},[14637,14638,14639,14640,14643],{"id":2464,"depth":155,"text":2464},{"id":13888,"depth":155,"text":13888},{"id":14033,"depth":155,"text":14033},{"id":14242,"depth":155,"text":14242,"children":14641},[14642],{"id":14617,"depth":169,"text":14617},{"id":9663,"depth":155,"text":9663},"2025-04-22T00:00:00.000Z","簡単にデバイスの位置情報を取得できる Web API Geolocation API の紹介です。",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1745236671/tsukiyama-blog/geo-location-api/geo-location-api_dwk5a7.png","/tech/geolocation-api",{"title":13869,"description":14645},"tech/geolocation-api",[5256,14652],"Web API","3-bkB7H0jOdw2C_H6Zgl_GkGX2d4v3-qjYxTR1R_Bv4",{"id":14655,"title":14656,"body":14657,"date":16398,"description":16399,"extension":381,"icon":2444,"meta":16400,"navigation":419,"ogImage":16401,"path":16402,"published":419,"publishedAt":2455,"seo":16403,"stem":16404,"tags":16405,"updatedAt":2455,"__hash__":16407},"tech/tech/mock-nuxt-import.md","Nuxt インポート関数をモックする mockNuxtImport 関数の紹介",{"type":8,"value":14658,"toc":16392},[14659,14663,14673,14676,14702,14705,14718,15056,15059,15159,15166,15695,15703,15706,15715,15718,16362,16372,16374,16389],[11,14660,14662],{"id":14661},"mocknuxtimport-とは","mockNuxtImport とは？",[16,14664,14665,14668,14669,14672],{},[90,14666,14667],{},"mockNuxtImport"," とは、Nuxt のインポート関数たちをモックする ",[90,14670,14671],{},"@nuxt/test-utils"," が提供するユーティリティ関数です。",[2523,14674],{"url":14675},"https://nuxt.com/docs/getting-started/testing#mocknuxtimport",[16,14677,14678,13794,14681,14684,14685,14688,14689,14692,14693,14695,14696,14698,14699,14701],{},[90,14679,14680],{},"useAsyncData",[90,14682,14683],{},"useFetch"," のようなインポート関数は Nuxt の内部で ",[90,14686,14687],{},"#imports"," から自動的にインポートされているので通常の ",[90,14690,14691],{},"vi.mock()"," ではうまくモックできません。",[35,14694],{},"\nそのため、これらの関数をテスト中に差し替えたい場合は、",[90,14697,14671],{}," が提供する ",[90,14700,14667],{}," を使うと便利です。",[11,14703,14704],{"id":14704},"実際に使ってみる",[16,14706,14707,14708,14710,14711,14713,14714,14717],{},"例えばこのような ",[90,14709,1865],{}," があるとします。",[35,14712],{},"\n（実際には ",[90,14715,14716],{},"useAsyncDate"," で ユーザー API を Fetch している）",[83,14719,14722],{"className":123,"code":14720,"filename":14721,"language":126,"meta":92,"style":92},"type User = {\n  familyName: string\n  firstName: string\n}\n\nexport const useUser = async () => {\n  const { data: user } = await useAsyncData\u003CUser>(async () => {\n    return {\n      firstName: 'kohei',\n      familyName: 'tsukiyama',\n    }\n  })\n\n  const toDisplayName = () => {\n    if (user.value === null) {\n      throw new Error('User is Missing')\n    }\n    const firstName = user.value.firstName\n    const familyName = user.value.familyName\n    const fullName = [firstName, familyName].filter(Boolean).join(' ')\n    return fullName.toUpperCase()\n  }\n\n  return { user, toDisplayName }\n}\n","user.ts",[90,14723,14724,14735,14745,14754,14758,14762,14781,14820,14826,14842,14858,14862,14868,14872,14887,14908,14929,14933,14953,14973,15017,15030,15034,15038,15052],{"__ignoreMap":92},[130,14725,14726,14728,14731,14733],{"class":132,"line":133},[130,14727,3726],{"class":546},[130,14729,14730],{"class":570}," User",[130,14732,555],{"class":554},[130,14734,166],{"class":162},[130,14736,14737,14740,14742],{"class":132,"line":155},[130,14738,14739],{"class":1925},"  familyName",[130,14741,163],{"class":554},[130,14743,14744],{"class":580}," string\n",[130,14746,14747,14750,14752],{"class":132,"line":169},[130,14748,14749],{"class":1925},"  firstName",[130,14751,163],{"class":554},[130,14753,14744],{"class":580},[130,14755,14756],{"class":132,"line":185},[130,14757,686],{"class":162},[130,14759,14760],{"class":132,"line":207},[130,14761,420],{"emptyLinePlaceholder":419},[130,14763,14764,14766,14768,14771,14773,14775,14777,14779],{"class":132,"line":224},[130,14765,137],{"class":136},[130,14767,547],{"class":546},[130,14769,14770],{"class":550}," useUser",[130,14772,555],{"class":554},[130,14774,558],{"class":546},[130,14776,1912],{"class":162},[130,14778,587],{"class":546},[130,14780,166],{"class":162},[130,14782,14783,14785,14787,14789,14791,14794,14796,14798,14800,14803,14805,14808,14810,14812,14814,14816,14818],{"class":132,"line":245},[130,14784,594],{"class":546},[130,14786,499],{"class":162},[130,14788,1926],{"class":1925},[130,14790,163],{"class":162},[130,14792,14793],{"class":597}," user",[130,14795,505],{"class":162},[130,14797,555],{"class":554},[130,14799,603],{"class":136},[130,14801,14802],{"class":143}," useAsyncData",[130,14804,608],{"class":162},[130,14806,14807],{"class":570},"User",[130,14809,618],{"class":162},[130,14811,148],{"class":158},[130,14813,1622],{"class":546},[130,14815,1912],{"class":162},[130,14817,587],{"class":546},[130,14819,166],{"class":162},[130,14821,14822,14824],{"class":132,"line":265},[130,14823,1182],{"class":136},[130,14825,166],{"class":162},[130,14827,14828,14831,14833,14835,14838,14840],{"class":132,"line":283},[130,14829,14830],{"class":158},"      firstName",[130,14832,163],{"class":162},[130,14834,194],{"class":193},[130,14836,14837],{"class":197},"kohei",[130,14839,201],{"class":193},[130,14841,204],{"class":162},[130,14843,14844,14847,14849,14851,14854,14856],{"class":132,"line":302},[130,14845,14846],{"class":158},"      familyName",[130,14848,163],{"class":162},[130,14850,194],{"class":193},[130,14852,14853],{"class":197},"tsukiyama",[130,14855,201],{"class":193},[130,14857,204],{"class":162},[130,14859,14860],{"class":132,"line":332},[130,14861,2105],{"class":162},[130,14863,14864,14866],{"class":132,"line":341},[130,14865,1981],{"class":162},[130,14867,338],{"class":158},[130,14869,14870],{"class":132,"line":349},[130,14871,420],{"emptyLinePlaceholder":419},[130,14873,14874,14876,14879,14881,14883,14885],{"class":132,"line":355},[130,14875,594],{"class":546},[130,14877,14878],{"class":550}," toDisplayName",[130,14880,555],{"class":554},[130,14882,1912],{"class":162},[130,14884,587],{"class":546},[130,14886,166],{"class":162},[130,14888,14889,14891,14893,14896,14898,14900,14902,14904,14906],{"class":132,"line":783},[130,14890,5910],{"class":136},[130,14892,561],{"class":158},[130,14894,14895],{"class":180},"user",[130,14897,235],{"class":162},[130,14899,5922],{"class":180},[130,14901,1167],{"class":554},[130,14903,1171],{"class":1170},[130,14905,1174],{"class":158},[130,14907,152],{"class":162},[130,14909,14910,14913,14915,14918,14920,14922,14925,14927],{"class":132,"line":793},[130,14911,14912],{"class":136},"      throw",[130,14914,6660],{"class":554},[130,14916,14917],{"class":143}," Error",[130,14919,148],{"class":158},[130,14921,201],{"class":193},[130,14923,14924],{"class":197},"User is Missing",[130,14926,201],{"class":193},[130,14928,338],{"class":158},[130,14930,14931],{"class":132,"line":798},[130,14932,2105],{"class":162},[130,14934,14935,14937,14940,14942,14944,14946,14948,14950],{"class":132,"line":806},[130,14936,5949],{"class":546},[130,14938,14939],{"class":597}," firstName",[130,14941,555],{"class":554},[130,14943,14793],{"class":180},[130,14945,235],{"class":162},[130,14947,5922],{"class":180},[130,14949,235],{"class":162},[130,14951,14952],{"class":180},"firstName\n",[130,14954,14955,14957,14960,14962,14964,14966,14968,14970],{"class":132,"line":1073},[130,14956,5949],{"class":546},[130,14958,14959],{"class":597}," familyName",[130,14961,555],{"class":554},[130,14963,14793],{"class":180},[130,14965,235],{"class":162},[130,14967,5922],{"class":180},[130,14969,235],{"class":162},[130,14971,14972],{"class":180},"familyName\n",[130,14974,14975,14977,14980,14982,14984,14987,14989,14991,14993,14995,14997,14999,15002,15004,15006,15009,15011,15013,15015],{"class":132,"line":1086},[130,14976,5949],{"class":546},[130,14978,14979],{"class":597}," fullName",[130,14981,555],{"class":554},[130,14983,10079],{"class":158},[130,14985,14986],{"class":180},"firstName",[130,14988,325],{"class":162},[130,14990,14959],{"class":180},[130,14992,10090],{"class":158},[130,14994,235],{"class":162},[130,14996,1334],{"class":143},[130,14998,148],{"class":158},[130,15000,15001],{"class":180},"Boolean",[130,15003,584],{"class":158},[130,15005,235],{"class":162},[130,15007,15008],{"class":143},"join",[130,15010,148],{"class":158},[130,15012,201],{"class":193},[130,15014,194],{"class":193},[130,15016,338],{"class":158},[130,15018,15019,15021,15023,15025,15028],{"class":132,"line":1092},[130,15020,1182],{"class":136},[130,15022,14979],{"class":180},[130,15024,235],{"class":162},[130,15026,15027],{"class":143},"toUpperCase",[130,15029,669],{"class":158},[130,15031,15032],{"class":132,"line":1128},[130,15033,352],{"class":162},[130,15035,15036],{"class":132,"line":1151},[130,15037,420],{"emptyLinePlaceholder":419},[130,15039,15040,15042,15044,15046,15048,15050],{"class":132,"line":1156},[130,15041,678],{"class":136},[130,15043,499],{"class":162},[130,15045,14793],{"class":180},[130,15047,325],{"class":162},[130,15049,14878],{"class":180},[130,15051,1998],{"class":162},[130,15053,15054],{"class":132,"line":1179},[130,15055,686],{"class":162},[16,15057,15058],{},"テンプレートはこんな感じです。",[83,15060,15062],{"className":2137,"code":15061,"filename":6210,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nconst user = await useUser()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>{{ user.toDisplayName() }}\u003C/p>\n  \u003C/div>\n\u003C/template>\n",[90,15063,15064,15084,15098,15106,15110,15118,15126,15143,15151],{"__ignoreMap":92},[130,15065,15066,15068,15070,15072,15074,15076,15078,15080,15082],{"class":132,"line":133},[130,15067,608],{"class":162},[130,15069,5698],{"class":2149},[130,15071,2154],{"class":2153},[130,15073,2157],{"class":2153},[130,15075,2160],{"class":162},[130,15077,2163],{"class":193},[130,15079,126],{"class":197},[130,15081,2163],{"class":193},[130,15083,2170],{"class":162},[130,15085,15086,15088,15090,15092,15094,15096],{"class":132,"line":155},[130,15087,1012],{"class":546},[130,15089,14793],{"class":597},[130,15091,555],{"class":554},[130,15093,603],{"class":136},[130,15095,14770],{"class":143},[130,15097,669],{"class":180},[130,15099,15100,15102,15104],{"class":132,"line":169},[130,15101,2193],{"class":162},[130,15103,5698],{"class":2149},[130,15105,2170],{"class":162},[130,15107,15108],{"class":132,"line":185},[130,15109,420],{"emptyLinePlaceholder":419},[130,15111,15112,15114,15116],{"class":132,"line":207},[130,15113,608],{"class":162},[130,15115,2130],{"class":2149},[130,15117,2170],{"class":162},[130,15119,15120,15122,15124],{"class":132,"line":224},[130,15121,2989],{"class":162},[130,15123,2683],{"class":2149},[130,15125,2170],{"class":162},[130,15127,15128,15130,15132,15134,15137,15139,15141],{"class":132,"line":245},[130,15129,3010],{"class":162},[130,15131,16],{"class":2149},[130,15133,618],{"class":162},[130,15135,15136],{"class":180},"{{ user.toDisplayName() }}",[130,15138,2193],{"class":162},[130,15140,16],{"class":2149},[130,15142,2170],{"class":162},[130,15144,15145,15147,15149],{"class":132,"line":265},[130,15146,3051],{"class":162},[130,15148,2683],{"class":2149},[130,15150,2170],{"class":162},[130,15152,15153,15155,15157],{"class":132,"line":283},[130,15154,2193],{"class":162},[130,15156,2130],{"class":2149},[130,15158,2170],{"class":162},[16,15160,15161,15162,15165],{},"ちゃんと大文字になり名と姓の間に半角スペースが入るか、",[90,15163,15164],{},"toDisplayName"," のテストをしたいとします。",[83,15167,15170],{"className":123,"code":15168,"filename":15169,"language":126,"meta":92,"style":92},"import { mockNuxtImport } from '@nuxt/test-utils/runtime'\nimport { it, expect, describe, vi } from 'vitest'\nimport { useUser } from '../useAsyncData'\n\n// useAsyncData のモック関数を定義\nconst { useAsyncData } = vi.hoisted(() => {\n  return {\n    useAsyncData: vi.fn().mockImplementation(() => {\n      return { data: {} }\n    }),\n  }\n})\n\n// Nuxt の useAsyncData を上で作成したモックに置き換える\nmockNuxtImport('useAsyncData', () => {\n  return useAsyncData\n})\n\ndescribe('useUser', () => {\n  it('正常系 ユーザーデータが取得できる場合', async () => {\n    const mockUser = ref({\n      firstName: 'test',\n      familyName: 'user',\n    })\n    // モックの戻り値を定義\n    useAsyncData.mockResolvedValue({\n      data: mockUser,\n    })\n    const { toDisplayName } = await useUser()\n    expect(toDisplayName()).toBe('TEST USER')\n  })\n  it('異常系 ユーザーデータが取得できなかった場合', async () => {\n    useAsyncData.mockResolvedValue({\n      data: ref(null),\n    })\n    const { toDisplayName } = await useUser()\n    expect(() => toDisplayName()).toThrow('User is Missing')\n  })\n})\n\n","user.spec.ts",[90,15171,15172,15192,15227,15246,15250,15255,15282,15288,15317,15333,15341,15345,15351,15355,15360,15380,15387,15393,15397,15419,15443,15458,15472,15486,15492,15497,15510,15521,15527,15545,15573,15579,15602,15614,15630,15636,15654,15683,15689],{"__ignoreMap":92},[130,15173,15174,15176,15178,15181,15183,15185,15187,15190],{"class":132,"line":133},[130,15175,493],{"class":136},[130,15177,499],{"class":162},[130,15179,15180],{"class":180}," mockNuxtImport",[130,15182,505],{"class":162},[130,15184,508],{"class":136},[130,15186,194],{"class":193},[130,15188,15189],{"class":197},"@nuxt/test-utils/runtime",[130,15191,515],{"class":193},[130,15193,15194,15196,15198,15201,15203,15206,15208,15211,15213,15216,15218,15220,15222,15225],{"class":132,"line":155},[130,15195,493],{"class":136},[130,15197,499],{"class":162},[130,15199,15200],{"class":180}," it",[130,15202,325],{"class":162},[130,15204,15205],{"class":180}," expect",[130,15207,325],{"class":162},[130,15209,15210],{"class":180}," describe",[130,15212,325],{"class":162},[130,15214,15215],{"class":180}," vi",[130,15217,505],{"class":162},[130,15219,508],{"class":136},[130,15221,194],{"class":193},[130,15223,15224],{"class":197},"vitest",[130,15226,515],{"class":193},[130,15228,15229,15231,15233,15235,15237,15239,15241,15244],{"class":132,"line":169},[130,15230,493],{"class":136},[130,15232,499],{"class":162},[130,15234,14770],{"class":180},[130,15236,505],{"class":162},[130,15238,508],{"class":136},[130,15240,194],{"class":193},[130,15242,15243],{"class":197},"../useAsyncData",[130,15245,515],{"class":193},[130,15247,15248],{"class":132,"line":185},[130,15249,420],{"emptyLinePlaceholder":419},[130,15251,15252],{"class":132,"line":207},[130,15253,15254],{"class":328},"// useAsyncData のモック関数を定義\n",[130,15256,15257,15259,15261,15263,15265,15267,15269,15271,15274,15276,15278,15280],{"class":132,"line":224},[130,15258,1012],{"class":546},[130,15260,499],{"class":162},[130,15262,14802],{"class":597},[130,15264,505],{"class":162},[130,15266,555],{"class":554},[130,15268,15215],{"class":180},[130,15270,235],{"class":162},[130,15272,15273],{"class":143},"hoisted",[130,15275,148],{"class":180},[130,15277,260],{"class":162},[130,15279,587],{"class":546},[130,15281,166],{"class":162},[130,15283,15284,15286],{"class":132,"line":245},[130,15285,678],{"class":136},[130,15287,166],{"class":162},[130,15289,15290,15293,15295,15297,15299,15302,15304,15306,15309,15311,15313,15315],{"class":132,"line":265},[130,15291,15292],{"class":158},"    useAsyncData",[130,15294,163],{"class":162},[130,15296,15215],{"class":180},[130,15298,235],{"class":162},[130,15300,15301],{"class":143},"fn",[130,15303,260],{"class":158},[130,15305,235],{"class":162},[130,15307,15308],{"class":143},"mockImplementation",[130,15310,148],{"class":158},[130,15312,260],{"class":162},[130,15314,587],{"class":546},[130,15316,166],{"class":162},[130,15318,15319,15322,15324,15326,15328,15331],{"class":132,"line":283},[130,15320,15321],{"class":136},"      return",[130,15323,499],{"class":162},[130,15325,1926],{"class":158},[130,15327,163],{"class":162},[130,15329,15330],{"class":162}," {}",[130,15332,1998],{"class":162},[130,15334,15335,15337,15339],{"class":132,"line":302},[130,15336,344],{"class":162},[130,15338,584],{"class":158},[130,15340,204],{"class":162},[130,15342,15343],{"class":132,"line":332},[130,15344,352],{"class":162},[130,15346,15347,15349],{"class":132,"line":341},[130,15348,358],{"class":162},[130,15350,338],{"class":180},[130,15352,15353],{"class":132,"line":349},[130,15354,420],{"emptyLinePlaceholder":419},[130,15356,15357],{"class":132,"line":355},[130,15358,15359],{"class":328},"// Nuxt の useAsyncData を上で作成したモックに置き換える\n",[130,15361,15362,15364,15366,15368,15370,15372,15374,15376,15378],{"class":132,"line":783},[130,15363,14667],{"class":143},[130,15365,148],{"class":180},[130,15367,201],{"class":193},[130,15369,14680],{"class":197},[130,15371,201],{"class":193},[130,15373,325],{"class":162},[130,15375,1912],{"class":162},[130,15377,587],{"class":546},[130,15379,166],{"class":162},[130,15381,15382,15384],{"class":132,"line":793},[130,15383,678],{"class":136},[130,15385,15386],{"class":180}," useAsyncData\n",[130,15388,15389,15391],{"class":132,"line":798},[130,15390,358],{"class":162},[130,15392,338],{"class":180},[130,15394,15395],{"class":132,"line":806},[130,15396,420],{"emptyLinePlaceholder":419},[130,15398,15399,15402,15404,15406,15409,15411,15413,15415,15417],{"class":132,"line":1073},[130,15400,15401],{"class":143},"describe",[130,15403,148],{"class":180},[130,15405,201],{"class":193},[130,15407,15408],{"class":197},"useUser",[130,15410,201],{"class":193},[130,15412,325],{"class":162},[130,15414,1912],{"class":162},[130,15416,587],{"class":546},[130,15418,166],{"class":162},[130,15420,15421,15424,15426,15428,15431,15433,15435,15437,15439,15441],{"class":132,"line":1086},[130,15422,15423],{"class":143},"  it",[130,15425,148],{"class":158},[130,15427,201],{"class":193},[130,15429,15430],{"class":197},"正常系 ユーザーデータが取得できる場合",[130,15432,201],{"class":193},[130,15434,325],{"class":162},[130,15436,558],{"class":546},[130,15438,1912],{"class":162},[130,15440,587],{"class":546},[130,15442,166],{"class":162},[130,15444,15445,15447,15450,15452,15454,15456],{"class":132,"line":1092},[130,15446,5949],{"class":546},[130,15448,15449],{"class":597}," mockUser",[130,15451,555],{"class":554},[130,15453,5823],{"class":143},[130,15455,148],{"class":158},[130,15457,152],{"class":162},[130,15459,15460,15462,15464,15466,15468,15470],{"class":132,"line":1128},[130,15461,14830],{"class":158},[130,15463,163],{"class":162},[130,15465,194],{"class":193},[130,15467,9927],{"class":197},[130,15469,201],{"class":193},[130,15471,204],{"class":162},[130,15473,15474,15476,15478,15480,15482,15484],{"class":132,"line":1151},[130,15475,14846],{"class":158},[130,15477,163],{"class":162},[130,15479,194],{"class":193},[130,15481,14895],{"class":197},[130,15483,201],{"class":193},[130,15485,204],{"class":162},[130,15487,15488,15490],{"class":132,"line":1156},[130,15489,344],{"class":162},[130,15491,338],{"class":158},[130,15493,15494],{"class":132,"line":1179},[130,15495,15496],{"class":328},"    // モックの戻り値を定義\n",[130,15498,15499,15501,15503,15506,15508],{"class":132,"line":1188},[130,15500,15292],{"class":180},[130,15502,235],{"class":162},[130,15504,15505],{"class":143},"mockResolvedValue",[130,15507,148],{"class":158},[130,15509,152],{"class":162},[130,15511,15512,15515,15517,15519],{"class":132,"line":1193},[130,15513,15514],{"class":158},"      data",[130,15516,163],{"class":162},[130,15518,15449],{"class":180},[130,15520,204],{"class":162},[130,15522,15523,15525],{"class":132,"line":1198},[130,15524,344],{"class":162},[130,15526,338],{"class":158},[130,15528,15529,15531,15533,15535,15537,15539,15541,15543],{"class":132,"line":1222},[130,15530,5949],{"class":546},[130,15532,499],{"class":162},[130,15534,14878],{"class":597},[130,15536,505],{"class":162},[130,15538,555],{"class":554},[130,15540,603],{"class":136},[130,15542,14770],{"class":143},[130,15544,669],{"class":158},[130,15546,15547,15550,15552,15554,15557,15559,15562,15564,15566,15569,15571],{"class":132,"line":1227},[130,15548,15549],{"class":143},"    expect",[130,15551,148],{"class":158},[130,15553,15164],{"class":143},[130,15555,15556],{"class":158},"())",[130,15558,235],{"class":162},[130,15560,15561],{"class":143},"toBe",[130,15563,148],{"class":158},[130,15565,201],{"class":193},[130,15567,15568],{"class":197},"TEST USER",[130,15570,201],{"class":193},[130,15572,338],{"class":158},[130,15574,15575,15577],{"class":132,"line":1232},[130,15576,1981],{"class":162},[130,15578,338],{"class":158},[130,15580,15581,15583,15585,15587,15590,15592,15594,15596,15598,15600],{"class":132,"line":1237},[130,15582,15423],{"class":143},[130,15584,148],{"class":158},[130,15586,201],{"class":193},[130,15588,15589],{"class":197},"異常系 ユーザーデータが取得できなかった場合",[130,15591,201],{"class":193},[130,15593,325],{"class":162},[130,15595,558],{"class":546},[130,15597,1912],{"class":162},[130,15599,587],{"class":546},[130,15601,166],{"class":162},[130,15603,15604,15606,15608,15610,15612],{"class":132,"line":1243},[130,15605,15292],{"class":180},[130,15607,235],{"class":162},[130,15609,15505],{"class":143},[130,15611,148],{"class":158},[130,15613,152],{"class":162},[130,15615,15616,15618,15620,15622,15624,15626,15628],{"class":132,"line":1256},[130,15617,15514],{"class":158},[130,15619,163],{"class":162},[130,15621,5823],{"class":143},[130,15623,148],{"class":158},[130,15625,5839],{"class":1170},[130,15627,584],{"class":158},[130,15629,204],{"class":162},[130,15631,15632,15634],{"class":132,"line":1268},[130,15633,344],{"class":162},[130,15635,338],{"class":158},[130,15637,15638,15640,15642,15644,15646,15648,15650,15652],{"class":132,"line":1273},[130,15639,5949],{"class":546},[130,15641,499],{"class":162},[130,15643,14878],{"class":597},[130,15645,505],{"class":162},[130,15647,555],{"class":554},[130,15649,603],{"class":136},[130,15651,14770],{"class":143},[130,15653,669],{"class":158},[130,15655,15656,15658,15660,15662,15664,15666,15668,15670,15673,15675,15677,15679,15681],{"class":132,"line":1301},[130,15657,15549],{"class":143},[130,15659,148],{"class":158},[130,15661,260],{"class":162},[130,15663,587],{"class":546},[130,15665,14878],{"class":143},[130,15667,15556],{"class":158},[130,15669,235],{"class":162},[130,15671,15672],{"class":143},"toThrow",[130,15674,148],{"class":158},[130,15676,201],{"class":193},[130,15678,14924],{"class":197},[130,15680,201],{"class":193},[130,15682,338],{"class":158},[130,15684,15685,15687],{"class":132,"line":1320},[130,15686,1981],{"class":162},[130,15688,338],{"class":158},[130,15690,15691,15693],{"class":132,"line":1325},[130,15692,358],{"class":162},[130,15694,338],{"class":180},[16,15696,15697,15699,15700,15702],{},[90,15698,14667],{}," を用いて ",[90,15701,14680],{}," をモックしテストできました。",[11,15704,15705],{"id":15705},"テスタビリティを高めるアプローチ",[16,15707,15708,15709,15711,15712,10523],{},"Nuxt のインポート関数をモックする方法を解説しましたが、すこし踏み込んで、",[35,15710],{},"\nそもそもインポート関数をモックしなくても",[106,15713,15714],{},"関数を切り出せばテストはもっとシンプルになります",[16,15716,15717],{},"テスタビリティを高めるために、先ほどのメソッドを高階関数として切り出してみます。",[83,15719,15721],{"className":123,"code":15720,"filename":14721,"language":126,"meta":92,"style":92},"type User = {\n  familyName: string\n  firstName: string\n}\n\nexport const useUser = async () => {\n  const { data: user } = await useAsyncData\u003CUser>(async () => {\n    return {\n      firstName: 'kohei',\n      familyName: 'tsukiyama',\n    }\n  })\n\n  const toDisplayName = createDisplayNameFormatter(user.value)\n\n  return { user, toDisplayName }\n}\n\n// 高階関数として切り出す\nconst createDisplayNameFormatter = (user: User | null) => {\n  if (user === null) {\n    throw new Error('User is Missing')\n  }\n  const firstName = user.firstName\n  const familyName = user.familyName\n  const fullName = [firstName, familyName].filter(Boolean).join(' ')\n\n  const toDisplayName = () => {\n    return fullName.toUpperCase()\n  }\n\n  return toDisplayName\n}\n\n// テスト\nif (import.meta.vitest) {\n  const { describe, it, expect } = import.meta.vitest\n  describe('useUser', () => {\n    it('正常系 ユーザーデータが取得できる場合', () => {\n      const mockUser = {\n        firstName: 'test',\n        familyName: 'user',\n      }\n      // 関数を切り出したので useAsyncData の影響を受けない\n      const toDisplayName = createDisplayNameFormatter(mockUser)\n      expect(toDisplayName()).toBe('TEST USER')\n    })\n    it('異常系 ユーザーデータが取得できなかった場合', () => {\n      expect(() => createDisplayNameFormatter(null)).toThrow('User is Missing')\n    })\n  })\n}\n\n",[90,15722,15723,15733,15741,15749,15753,15757,15775,15811,15817,15831,15845,15849,15855,15859,15880,15884,15898,15902,15906,15911,15937,15953,15972,15976,15990,16004,16044,16048,16062,16074,16078,16082,16089,16093,16097,16102,16121,16153,16174,16195,16206,16221,16236,16240,16245,16262,16287,16293,16313,16346,16352,16358],{"__ignoreMap":92},[130,15724,15725,15727,15729,15731],{"class":132,"line":133},[130,15726,3726],{"class":546},[130,15728,14730],{"class":570},[130,15730,555],{"class":554},[130,15732,166],{"class":162},[130,15734,15735,15737,15739],{"class":132,"line":155},[130,15736,14739],{"class":1925},[130,15738,163],{"class":554},[130,15740,14744],{"class":580},[130,15742,15743,15745,15747],{"class":132,"line":169},[130,15744,14749],{"class":1925},[130,15746,163],{"class":554},[130,15748,14744],{"class":580},[130,15750,15751],{"class":132,"line":185},[130,15752,686],{"class":162},[130,15754,15755],{"class":132,"line":207},[130,15756,420],{"emptyLinePlaceholder":419},[130,15758,15759,15761,15763,15765,15767,15769,15771,15773],{"class":132,"line":224},[130,15760,137],{"class":136},[130,15762,547],{"class":546},[130,15764,14770],{"class":550},[130,15766,555],{"class":554},[130,15768,558],{"class":546},[130,15770,1912],{"class":162},[130,15772,587],{"class":546},[130,15774,166],{"class":162},[130,15776,15777,15779,15781,15783,15785,15787,15789,15791,15793,15795,15797,15799,15801,15803,15805,15807,15809],{"class":132,"line":245},[130,15778,594],{"class":546},[130,15780,499],{"class":162},[130,15782,1926],{"class":1925},[130,15784,163],{"class":162},[130,15786,14793],{"class":597},[130,15788,505],{"class":162},[130,15790,555],{"class":554},[130,15792,603],{"class":136},[130,15794,14802],{"class":143},[130,15796,608],{"class":162},[130,15798,14807],{"class":570},[130,15800,618],{"class":162},[130,15802,148],{"class":158},[130,15804,1622],{"class":546},[130,15806,1912],{"class":162},[130,15808,587],{"class":546},[130,15810,166],{"class":162},[130,15812,15813,15815],{"class":132,"line":265},[130,15814,1182],{"class":136},[130,15816,166],{"class":162},[130,15818,15819,15821,15823,15825,15827,15829],{"class":132,"line":283},[130,15820,14830],{"class":158},[130,15822,163],{"class":162},[130,15824,194],{"class":193},[130,15826,14837],{"class":197},[130,15828,201],{"class":193},[130,15830,204],{"class":162},[130,15832,15833,15835,15837,15839,15841,15843],{"class":132,"line":302},[130,15834,14846],{"class":158},[130,15836,163],{"class":162},[130,15838,194],{"class":193},[130,15840,14853],{"class":197},[130,15842,201],{"class":193},[130,15844,204],{"class":162},[130,15846,15847],{"class":132,"line":332},[130,15848,2105],{"class":162},[130,15850,15851,15853],{"class":132,"line":341},[130,15852,1981],{"class":162},[130,15854,338],{"class":158},[130,15856,15857],{"class":132,"line":349},[130,15858,420],{"emptyLinePlaceholder":419},[130,15860,15861,15863,15865,15867,15870,15872,15874,15876,15878],{"class":132,"line":355},[130,15862,594],{"class":546},[130,15864,14878],{"class":597},[130,15866,555],{"class":554},[130,15868,15869],{"class":143}," createDisplayNameFormatter",[130,15871,148],{"class":158},[130,15873,14895],{"class":180},[130,15875,235],{"class":162},[130,15877,5922],{"class":180},[130,15879,338],{"class":158},[130,15881,15882],{"class":132,"line":783},[130,15883,420],{"emptyLinePlaceholder":419},[130,15885,15886,15888,15890,15892,15894,15896],{"class":132,"line":793},[130,15887,678],{"class":136},[130,15889,499],{"class":162},[130,15891,14793],{"class":180},[130,15893,325],{"class":162},[130,15895,14878],{"class":180},[130,15897,1998],{"class":162},[130,15899,15900],{"class":132,"line":798},[130,15901,686],{"class":162},[130,15903,15904],{"class":132,"line":806},[130,15905,420],{"emptyLinePlaceholder":419},[130,15907,15908],{"class":132,"line":1073},[130,15909,15910],{"class":328},"// 高階関数として切り出す\n",[130,15912,15913,15915,15917,15919,15921,15923,15925,15927,15929,15931,15933,15935],{"class":132,"line":1086},[130,15914,1012],{"class":546},[130,15916,15869],{"class":550},[130,15918,555],{"class":554},[130,15920,561],{"class":162},[130,15922,14895],{"class":564},[130,15924,163],{"class":554},[130,15926,14730],{"class":570},[130,15928,2061],{"class":554},[130,15930,1171],{"class":580},[130,15932,584],{"class":162},[130,15934,587],{"class":546},[130,15936,166],{"class":162},[130,15938,15939,15941,15943,15945,15947,15949,15951],{"class":132,"line":1092},[130,15940,1159],{"class":136},[130,15942,561],{"class":158},[130,15944,14895],{"class":180},[130,15946,1167],{"class":554},[130,15948,1171],{"class":1170},[130,15950,1174],{"class":158},[130,15952,152],{"class":162},[130,15954,15955,15958,15960,15962,15964,15966,15968,15970],{"class":132,"line":1128},[130,15956,15957],{"class":136},"    throw",[130,15959,6660],{"class":554},[130,15961,14917],{"class":143},[130,15963,148],{"class":158},[130,15965,201],{"class":193},[130,15967,14924],{"class":197},[130,15969,201],{"class":193},[130,15971,338],{"class":158},[130,15973,15974],{"class":132,"line":1151},[130,15975,352],{"class":162},[130,15977,15978,15980,15982,15984,15986,15988],{"class":132,"line":1156},[130,15979,594],{"class":546},[130,15981,14939],{"class":597},[130,15983,555],{"class":554},[130,15985,14793],{"class":180},[130,15987,235],{"class":162},[130,15989,14952],{"class":180},[130,15991,15992,15994,15996,15998,16000,16002],{"class":132,"line":1179},[130,15993,594],{"class":546},[130,15995,14959],{"class":597},[130,15997,555],{"class":554},[130,15999,14793],{"class":180},[130,16001,235],{"class":162},[130,16003,14972],{"class":180},[130,16005,16006,16008,16010,16012,16014,16016,16018,16020,16022,16024,16026,16028,16030,16032,16034,16036,16038,16040,16042],{"class":132,"line":1188},[130,16007,594],{"class":546},[130,16009,14979],{"class":597},[130,16011,555],{"class":554},[130,16013,10079],{"class":158},[130,16015,14986],{"class":180},[130,16017,325],{"class":162},[130,16019,14959],{"class":180},[130,16021,10090],{"class":158},[130,16023,235],{"class":162},[130,16025,1334],{"class":143},[130,16027,148],{"class":158},[130,16029,15001],{"class":180},[130,16031,584],{"class":158},[130,16033,235],{"class":162},[130,16035,15008],{"class":143},[130,16037,148],{"class":158},[130,16039,201],{"class":193},[130,16041,194],{"class":193},[130,16043,338],{"class":158},[130,16045,16046],{"class":132,"line":1193},[130,16047,420],{"emptyLinePlaceholder":419},[130,16049,16050,16052,16054,16056,16058,16060],{"class":132,"line":1198},[130,16051,594],{"class":546},[130,16053,14878],{"class":550},[130,16055,555],{"class":554},[130,16057,1912],{"class":162},[130,16059,587],{"class":546},[130,16061,166],{"class":162},[130,16063,16064,16066,16068,16070,16072],{"class":132,"line":1222},[130,16065,1182],{"class":136},[130,16067,14979],{"class":180},[130,16069,235],{"class":162},[130,16071,15027],{"class":143},[130,16073,669],{"class":158},[130,16075,16076],{"class":132,"line":1227},[130,16077,352],{"class":162},[130,16079,16080],{"class":132,"line":1232},[130,16081,420],{"emptyLinePlaceholder":419},[130,16083,16084,16086],{"class":132,"line":1237},[130,16085,678],{"class":136},[130,16087,16088],{"class":180}," toDisplayName\n",[130,16090,16091],{"class":132,"line":1243},[130,16092,686],{"class":162},[130,16094,16095],{"class":132,"line":1256},[130,16096,420],{"emptyLinePlaceholder":419},[130,16098,16099],{"class":132,"line":1268},[130,16100,16101],{"class":328},"// テスト\n",[130,16103,16104,16106,16108,16110,16112,16114,16116,16119],{"class":132,"line":1273},[130,16105,2316],{"class":136},[130,16107,561],{"class":180},[130,16109,493],{"class":136},[130,16111,235],{"class":162},[130,16113,9829],{"class":597},[130,16115,235],{"class":162},[130,16117,16118],{"class":180},"vitest) ",[130,16120,152],{"class":162},[130,16122,16123,16125,16127,16129,16131,16133,16135,16137,16139,16141,16144,16146,16148,16150],{"class":132,"line":1301},[130,16124,594],{"class":546},[130,16126,499],{"class":162},[130,16128,15210],{"class":597},[130,16130,325],{"class":162},[130,16132,15200],{"class":597},[130,16134,325],{"class":162},[130,16136,15205],{"class":597},[130,16138,505],{"class":162},[130,16140,555],{"class":554},[130,16142,16143],{"class":136}," import",[130,16145,235],{"class":162},[130,16147,9829],{"class":597},[130,16149,235],{"class":162},[130,16151,16152],{"class":180},"vitest\n",[130,16154,16155,16158,16160,16162,16164,16166,16168,16170,16172],{"class":132,"line":1320},[130,16156,16157],{"class":143},"  describe",[130,16159,148],{"class":158},[130,16161,201],{"class":193},[130,16163,15408],{"class":197},[130,16165,201],{"class":193},[130,16167,325],{"class":162},[130,16169,1912],{"class":162},[130,16171,587],{"class":546},[130,16173,166],{"class":162},[130,16175,16176,16179,16181,16183,16185,16187,16189,16191,16193],{"class":132,"line":1325},[130,16177,16178],{"class":143},"    it",[130,16180,148],{"class":158},[130,16182,201],{"class":193},[130,16184,15430],{"class":197},[130,16186,201],{"class":193},[130,16188,325],{"class":162},[130,16190,1912],{"class":162},[130,16192,587],{"class":546},[130,16194,166],{"class":162},[130,16196,16197,16200,16202,16204],{"class":132,"line":1344},[130,16198,16199],{"class":546},"      const",[130,16201,15449],{"class":597},[130,16203,555],{"class":554},[130,16205,166],{"class":162},[130,16207,16208,16211,16213,16215,16217,16219],{"class":132,"line":1349},[130,16209,16210],{"class":158},"        firstName",[130,16212,163],{"class":162},[130,16214,194],{"class":193},[130,16216,9927],{"class":197},[130,16218,201],{"class":193},[130,16220,204],{"class":162},[130,16222,16223,16226,16228,16230,16232,16234],{"class":132,"line":1354},[130,16224,16225],{"class":158},"        familyName",[130,16227,163],{"class":162},[130,16229,194],{"class":193},[130,16231,14895],{"class":197},[130,16233,201],{"class":193},[130,16235,204],{"class":162},[130,16237,16238],{"class":132,"line":1359},[130,16239,7739],{"class":162},[130,16241,16242],{"class":132,"line":1365},[130,16243,16244],{"class":328},"      // 関数を切り出したので useAsyncData の影響を受けない\n",[130,16246,16247,16249,16251,16253,16255,16257,16260],{"class":132,"line":1379},[130,16248,16199],{"class":546},[130,16250,14878],{"class":597},[130,16252,555],{"class":554},[130,16254,15869],{"class":143},[130,16256,148],{"class":158},[130,16258,16259],{"class":180},"mockUser",[130,16261,338],{"class":158},[130,16263,16264,16267,16269,16271,16273,16275,16277,16279,16281,16283,16285],{"class":132,"line":1391},[130,16265,16266],{"class":143},"      expect",[130,16268,148],{"class":158},[130,16270,15164],{"class":143},[130,16272,15556],{"class":158},[130,16274,235],{"class":162},[130,16276,15561],{"class":143},[130,16278,148],{"class":158},[130,16280,201],{"class":193},[130,16282,15568],{"class":197},[130,16284,201],{"class":193},[130,16286,338],{"class":158},[130,16288,16289,16291],{"class":132,"line":1396},[130,16290,344],{"class":162},[130,16292,338],{"class":158},[130,16294,16295,16297,16299,16301,16303,16305,16307,16309,16311],{"class":132,"line":1419},[130,16296,16178],{"class":143},[130,16298,148],{"class":158},[130,16300,201],{"class":193},[130,16302,15589],{"class":197},[130,16304,201],{"class":193},[130,16306,325],{"class":162},[130,16308,1912],{"class":162},[130,16310,587],{"class":546},[130,16312,166],{"class":162},[130,16314,16315,16317,16319,16321,16323,16325,16327,16329,16332,16334,16336,16338,16340,16342,16344],{"class":132,"line":1425},[130,16316,16266],{"class":143},[130,16318,148],{"class":158},[130,16320,260],{"class":162},[130,16322,587],{"class":546},[130,16324,15869],{"class":143},[130,16326,148],{"class":158},[130,16328,5839],{"class":1170},[130,16330,16331],{"class":158},"))",[130,16333,235],{"class":162},[130,16335,15672],{"class":143},[130,16337,148],{"class":158},[130,16339,201],{"class":193},[130,16341,14924],{"class":197},[130,16343,201],{"class":193},[130,16345,338],{"class":158},[130,16347,16348,16350],{"class":132,"line":1445},[130,16349,344],{"class":162},[130,16351,338],{"class":158},[130,16353,16354,16356],{"class":132,"line":1454},[130,16355,1981],{"class":162},[130,16357,338],{"class":158},[130,16359,16360],{"class":132,"line":1459},[130,16361,686],{"class":162},[16,16363,16364,16365,16368,16369,16371],{},"関数を切り出し",[106,16366,16367],{},"凝集度を低く","することにより ",[90,16370,14680],{}," の影響を受けないようになり、モックを作成せずテストが書けるようになりました。",[11,16373,5032],{"id":5032},[2566,16375,16376,16384],{},[2569,16377,16378],{},[106,16379,16380,16381,16383],{},"Nuxt のインポート関数をモックするには ",[90,16382,14667],{}," を使う",[2569,16385,16386],{},[106,16387,16388],{},"関数を切り出すと凝集度が低くなりテスタビリティが高まる",[2420,16390,16391],{},"html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sywW5, html code.shiki .sywW5{--shiki-light:#E2931D;--shiki-default:#FFB757;--shiki-dark:#B392F0}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .s-3tI, html code.shiki .s-3tI{--shiki-light:#E53935;--shiki-default:#FFB757;--shiki-dark:#FFAB70}html pre.shiki code .snYqn, html code.shiki .snYqn{--shiki-light:#E2931D;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .s8Xov, html code.shiki .s8Xov{--shiki-light:#90A4AE;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .s4Pz2, html code.shiki .s4Pz2{--shiki-light:#39ADB5;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .senS2, html code.shiki .senS2{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#FFB757;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}",{"title":92,"searchDepth":169,"depth":169,"links":16393},[16394,16395,16396,16397],{"id":14661,"depth":155,"text":14662},{"id":14704,"depth":155,"text":14704},{"id":15705,"depth":155,"text":15705},{"id":5032,"depth":155,"text":5032},"2025-04-15T00:00:00.000Z","useAsyncData や useFetch のような Nuxt インポート関数をモックするのに便利な mockNuxtImport の紹介と凝集度を低くしテスタビリティを高める方法を紹介します。",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1744641614/tsukiyama-blog/mock-nuxt-import/mock-nuxt-import-thumbnail_zqckp3.png","/tech/mock-nuxt-import",{"title":14656,"description":16399},"tech/mock-nuxt-import",[2452,12553,16406],"Nuxt Test Utils","aFLjapuRouad5ud_SX80g5VT-5ZNkj4kNpvQcr4iuhc",{"id":16409,"title":71,"body":16410,"date":18444,"description":18445,"extension":381,"icon":2444,"meta":18446,"navigation":419,"ogImage":18447,"path":68,"published":419,"publishedAt":2455,"seo":18448,"stem":18449,"tags":18450,"updatedAt":2455,"__hash__":18452},"tech/tech/nuxt-content-v3-blog.md",{"type":8,"value":16411,"toc":18419},[16412,16418,16426,16428,16440,16450,16460,16466,16469,16472,16478,16484,16488,16491,16494,16498,16501,16504,16508,16511,16514,16517,16521,16524,16546,16552,16575,16580,16586,16591,16595,16598,16617,16621,16624,16642,16646,16649,16652,16669,16675,16697,16702,16799,16802,16805,16808,16823,16829,16836,17072,17078,17083,17088,17091,17094,17097,17107,17110,17116,17126,17129,17340,17343,17357,17413,17417,17422,17776,17791,17794,17800,17846,17852,17857,17860,17866,18338,18341,18346,18349,18360,18381,18386,18389,18391,18398,18401,18410,18413,18416],[16413,16414,16415],"blockquote",{},[16,16416,16417],{},"ブログはソフトウェア開発者のセルフマーケティングで使える最良のメディアのひとつだ。実際、自分のキャリアを大事に考えるすべてのソフトウェア開発者は、ブログの作成に投資すべきだと私は強く思っている。",[16,16419,16425],{"className":16420},[16421,16422,16423,16424],"text-right","text-xs","italic","opacity-80","ジョン・ソンメズ. SOFT SKILLS ソフトウェア開発者の人生マニュアル 第2版 (p.186).",[11,16427,2464],{"id":2464},[16,16429,16430,16431,2499,16434,16436,16437,16439],{},"はじめまして、フリーランスのエンジニアとして働いている",[106,16432,16433],{},"つきやま",[35,16435],{},"\nVue, Nuxt, CSS が好きです。",[35,16438],{},"\n技術以外だと最近はポケポケと短歌を嗜んでいます。",[16,16441,16442,16443,16445,16446,16449],{},"この度、個人ブログを作る運びとなり、本記事は記念すべき一本目の記事です。",[35,16444],{},"\nせっかくなので一本目の記事は本ブログのような",[106,16447,16448],{},"個人ブログを爆速で作る方法","の記事を書こうと思います。",[16,16451,16452,16453,16456,16457,16459],{},"記事のテーマとして",[106,16454,16455],{},"個人ブログを爆速で作る","と掲げているので、ブログの根幹となる機能の解説しかしません。",[35,16458],{},"\n（＝細かな機能やUIについては解説しないです）",[16,16461,16462,16463,16465],{},"Nuxt Content は 2025 年 1 月に v3 がリリースされました。",[35,16464],{},"\nv3 の主な機能は公式ブログにまとめられています。",[2523,16467],{"url":16468},"https://content.nuxt.com/blog/v3",[11,16470,16471],{"id":16471},"事前準備",[16,16473,16474,16475,16477],{},"さっそく実装に入りたいところですが、実装に入る前に各種アカウント作成をする必要があるので作成がまだの方は作成をお願いします。",[35,16476],{},"\n（すでにアカウントお持ちの方は飛ばしてください。）",[16,16479,16480,16481,16483],{},"本記事では Nuxt Hub を利用してデプロイを行います。",[35,16482],{},"\nNuxt Hub を利用する際に必要なアカウント類の登録を行います。",[76,16485,16487],{"id":16486},"github","GitHub",[16,16489,16490],{},"GitHub アカウントと公開するサービスのリポジトリを用意をお願いします。",[2523,16492],{"url":16493},"https://github.com/signup",[76,16495,16497],{"id":16496},"cloudflare","Cloudflare",[16,16499,16500],{},"Cloudflare Pages にホスティングするのでアカウントの作成をお願いします。",[2523,16502],{"url":16503},"https://dash.cloudflare.com/sign-up",[76,16505,16507],{"id":16506},"nuxt-hub","Nuxt Hub",[16,16509,16510],{},"Nuxt Hub を用いて Cloudflare にデプロイするのでアカウント作成をお願いします。",[2523,16512],{"url":16513},"https://admin.hub.nuxt.com/?utm_source=hub-docs&utm_medium=header&utm_campaign=signup",[11,16515,16516],{"id":16516},"環境構築",[76,16518,16520],{"id":16519},"nuxt-インストール","Nuxt インストール",[2523,16522],{"url":16523},"https://nuxt.com/docs/getting-started/installation",[83,16525,16527],{"className":5388,"code":16526,"language":5390,"meta":92,"style":92},"$ npm create nuxt sample-blog\n",[90,16528,16529],{"__ignoreMap":92},[130,16530,16531,16534,16537,16540,16543],{"class":132,"line":133},[130,16532,16533],{"class":570},"$",[130,16535,16536],{"class":197}," npm",[130,16538,16539],{"class":197}," create",[130,16541,16542],{"class":197}," nuxt",[130,16544,16545],{"class":197}," sample-blog\n",[16,16547,16548,16549,16551],{},"プロジェクト名は任意の名前をつけてください。",[35,16550],{},"\nインストールが済んだらディレクトリを移動して、開発サーバーを起動してみましょう。",[83,16553,16555],{"className":5388,"code":16554,"language":5390,"meta":92,"style":92},"cd sample-blog\nnpm run dev\n",[90,16556,16557,16565],{"__ignoreMap":92},[130,16558,16559,16563],{"class":132,"line":133},[130,16560,16562],{"class":16561},"sFoIN","cd",[130,16564,16545],{"class":197},[130,16566,16567,16569,16572],{"class":132,"line":155},[130,16568,5465],{"class":570},[130,16570,16571],{"class":197}," run",[130,16573,16574],{"class":197}," dev\n",[16,16576,16577],{},[2692,16578],{"alt":92,"src":16579},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1743334480/tsukiyama-blog/nuxt-content-v3-blog/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-03-30_20.29.14_yc0omm.png",[16,16581,16582,16585],{},[90,16583,16584],{},"localhost:3000","にアクセスして Welcome ページが表示されていれば完了です。",[16,16587,16588],{},[106,16589,16590],{},"デプロイの際にGitHubリポジトリと紐づける必要があるのでリポジトリの作成・紐付けも行います。",[76,16592,16594],{"id":16593},"nuxt-content-インストール","Nuxt Content インストール",[2523,16596],{"url":16597},"https://content.nuxt.com/docs/getting-started/installation",[83,16599,16601],{"className":5388,"code":16600,"language":5390,"meta":92,"style":92},"npx nuxi module add content\n",[90,16602,16603],{"__ignoreMap":92},[130,16604,16605,16607,16610,16612,16614],{"class":132,"line":133},[130,16606,5397],{"class":570},[130,16608,16609],{"class":197}," nuxi",[130,16611,5403],{"class":197},[130,16613,5406],{"class":197},[130,16615,16616],{"class":197}," content\n",[76,16618,16620],{"id":16619},"nuxt-hub-インストール","Nuxt Hub インストール",[2523,16622],{"url":16623},"https://hub.nuxt.com/docs/getting-started/installation",[83,16625,16627],{"className":5388,"code":16626,"language":5390,"meta":92,"style":92},"npx nuxi module add hub\n",[90,16628,16629],{"__ignoreMap":92},[130,16630,16631,16633,16635,16637,16639],{"class":132,"line":133},[130,16632,5397],{"class":570},[130,16634,16609],{"class":197},[130,16636,5403],{"class":197},[130,16638,5406],{"class":197},[130,16640,16641],{"class":197}," hub\n",[76,16643,16645],{"id":16644},"tailwind-css-nice-to-have","Tailwind CSS (Nice to Have)",[16,16647,16648],{},"（Tailwind CSS はインストールしなくても問題ないです。）",[2523,16650],{"url":16651},"https://tailwindcss.com/docs/installation/using-vite",[83,16653,16655],{"className":5388,"code":16654,"language":5390,"meta":92,"style":92},"npm install tailwindcss @tailwindcss/vite\n",[90,16656,16657],{"__ignoreMap":92},[130,16658,16659,16661,16663,16666],{"class":132,"line":133},[130,16660,5465],{"class":570},[130,16662,5474],{"class":197},[130,16664,16665],{"class":197}," tailwindcss",[130,16667,16668],{"class":197}," @tailwindcss/vite\n",[16,16670,16671,16674],{},[90,16672,16673],{},"~/assets/css/tailwind.css","を新規作成します。",[83,16676,16681],{"className":16677,"code":16678,"filename":16679,"language":16680,"meta":92,"style":92},"language-css shiki shiki-themes material-theme-lighter github-dark-high-contrast github-dark","@import \"tailwindcss\";\n","tailwind.css","css",[90,16682,16683],{"__ignoreMap":92},[130,16684,16685,16688,16690,16693,16695],{"class":132,"line":133},[130,16686,16687],{"class":136},"@import",[130,16689,11687],{"class":193},[130,16691,16692],{"class":197},"tailwindcss",[130,16694,2163],{"class":193},[130,16696,10742],{"class":162},[16,16698,16699,16701],{},[90,16700,5282],{},"に Tailwind CSS の記述を追加します。",[83,16703,16705],{"className":123,"code":16704,"filename":5282,"language":126,"meta":92,"style":92},"import tailwindcss from '@tailwindcss/vite'\n\nexport default defineNuxtConfig({\n  // ...\n  css: ['~/assets/css/tailwind.css'],\n  vite: {\n    plugins: [tailwindcss()],\n  },\n})\n",[90,16706,16707,16723,16727,16739,16743,16762,16771,16787,16793],{"__ignoreMap":92},[130,16708,16709,16711,16714,16716,16718,16721],{"class":132,"line":133},[130,16710,493],{"class":136},[130,16712,16713],{"class":180}," tailwindcss ",[130,16715,886],{"class":136},[130,16717,194],{"class":193},[130,16719,16720],{"class":197},"@tailwindcss/vite",[130,16722,515],{"class":193},[130,16724,16725],{"class":132,"line":155},[130,16726,420],{"emptyLinePlaceholder":419},[130,16728,16729,16731,16733,16735,16737],{"class":132,"line":169},[130,16730,137],{"class":136},[130,16732,140],{"class":136},[130,16734,5293],{"class":143},[130,16736,148],{"class":147},[130,16738,152],{"class":151},[130,16740,16741],{"class":132,"line":185},[130,16742,10470],{"class":328},[130,16744,16745,16748,16750,16752,16754,16756,16758,16760],{"class":132,"line":207},[130,16746,16747],{"class":158},"  css",[130,16749,163],{"class":162},[130,16751,10079],{"class":180},[130,16753,201],{"class":193},[130,16755,16673],{"class":197},[130,16757,201],{"class":193},[130,16759,10090],{"class":180},[130,16761,204],{"class":151},[130,16763,16764,16767,16769],{"class":132,"line":224},[130,16765,16766],{"class":158},"  vite",[130,16768,163],{"class":162},[130,16770,166],{"class":162},[130,16772,16773,16776,16778,16780,16782,16785],{"class":132,"line":245},[130,16774,16775],{"class":158},"    plugins",[130,16777,163],{"class":162},[130,16779,10079],{"class":180},[130,16781,16692],{"class":143},[130,16783,16784],{"class":180},"()]",[130,16786,204],{"class":162},[130,16788,16789,16791],{"class":132,"line":265},[130,16790,1981],{"class":162},[130,16792,204],{"class":151},[130,16794,16795,16797],{"class":132,"line":283},[130,16796,358],{"class":151},[130,16798,338],{"class":147},[11,16800,16801],{"id":16801},"デプロイしてみる",[16,16803,16804],{},"一通りの環境構築を終えたのでこの段階で一旦デプロイしてみましょう。",[76,16806,16807],{"id":16807},"デプロイコマンド",[83,16809,16811],{"className":5388,"code":16810,"language":5390,"meta":92,"style":92},"npx nuxthub deploy\n",[90,16812,16813],{"__ignoreMap":92},[130,16814,16815,16817,16820],{"class":132,"line":133},[130,16816,5397],{"class":570},[130,16818,16819],{"class":197}," nuxthub",[130,16821,16822],{"class":197}," deploy\n",[16,16824,16825,16826,16828],{},"デプロイコマンドを実行するといくつか質問されます",[35,16827],{},"\n基本的にデフォルトの回答で大丈夫だと思います。",[16,16830,16831,16832,16835],{},"region だけ ",[90,16833,16834],{},"Asia Pacific"," を選びました。",[83,16837,16839],{"className":5388,"code":16838,"language":5390,"meta":92,"style":92},"$ npx nuxthub deploy\nNuxtHub CLI\nℹ No project is linked with the NUXT_HUB_PROJECT_KEY environment variable.\n│\n◇  Deploy ~/projects/sample-blog to NuxtHub?\n│  Yes\n│\n◇  Select a project\n│  Create a new project\n│\n◇  Project name\n│  sample-blog\n│\n◇  Select a region for the storage\n│  Asia Pacific\n│\n◇  Production branch (git)\n│  main\n✔ Project sample-blog created\n✔ Connected to tsukiyama-3 team.\n✔ Linked to sample-blog project.\n",[90,16840,16841,16852,16860,16892,16897,16914,16922,16926,16938,16951,16955,16965,16972,16976,16995,17005,17009,17022,17029,17043,17058],{"__ignoreMap":92},[130,16842,16843,16845,16848,16850],{"class":132,"line":133},[130,16844,16533],{"class":570},[130,16846,16847],{"class":197}," npx",[130,16849,16819],{"class":197},[130,16851,16822],{"class":197},[130,16853,16854,16857],{"class":132,"line":155},[130,16855,16856],{"class":570},"NuxtHub",[130,16858,16859],{"class":197}," CLI\n",[130,16861,16862,16865,16868,16871,16874,16877,16880,16883,16886,16889],{"class":132,"line":169},[130,16863,16864],{"class":570},"ℹ",[130,16866,16867],{"class":197}," No",[130,16869,16870],{"class":197}," project",[130,16872,16873],{"class":197}," is",[130,16875,16876],{"class":197}," linked",[130,16878,16879],{"class":197}," with",[130,16881,16882],{"class":197}," the",[130,16884,16885],{"class":197}," NUXT_HUB_PROJECT_KEY",[130,16887,16888],{"class":197}," environment",[130,16890,16891],{"class":197}," variable.\n",[130,16893,16894],{"class":132,"line":185},[130,16895,16896],{"class":570},"│\n",[130,16898,16899,16902,16905,16908,16911],{"class":132,"line":207},[130,16900,16901],{"class":570},"◇",[130,16903,16904],{"class":197},"  Deploy",[130,16906,16907],{"class":197}," ~/projects/sample-blog",[130,16909,16910],{"class":197}," to",[130,16912,16913],{"class":197}," NuxtHub?\n",[130,16915,16916,16919],{"class":132,"line":224},[130,16917,16918],{"class":570},"│",[130,16920,16921],{"class":197},"  Yes\n",[130,16923,16924],{"class":132,"line":245},[130,16925,16896],{"class":570},[130,16927,16928,16930,16933,16935],{"class":132,"line":265},[130,16929,16901],{"class":570},[130,16931,16932],{"class":197},"  Select",[130,16934,12262],{"class":197},[130,16936,16937],{"class":197}," project\n",[130,16939,16940,16942,16945,16947,16949],{"class":132,"line":283},[130,16941,16918],{"class":570},[130,16943,16944],{"class":197},"  Create",[130,16946,12262],{"class":197},[130,16948,6660],{"class":197},[130,16950,16937],{"class":197},[130,16952,16953],{"class":132,"line":302},[130,16954,16896],{"class":570},[130,16956,16957,16959,16962],{"class":132,"line":332},[130,16958,16901],{"class":570},[130,16960,16961],{"class":197},"  Project",[130,16963,16964],{"class":197}," name\n",[130,16966,16967,16969],{"class":132,"line":341},[130,16968,16918],{"class":570},[130,16970,16971],{"class":197},"  sample-blog\n",[130,16973,16974],{"class":132,"line":349},[130,16975,16896],{"class":570},[130,16977,16978,16980,16982,16984,16987,16990,16992],{"class":132,"line":355},[130,16979,16901],{"class":570},[130,16981,16932],{"class":197},[130,16983,12262],{"class":197},[130,16985,16986],{"class":197}," region",[130,16988,16989],{"class":197}," for",[130,16991,16882],{"class":197},[130,16993,16994],{"class":197}," storage\n",[130,16996,16997,16999,17002],{"class":132,"line":783},[130,16998,16918],{"class":570},[130,17000,17001],{"class":197},"  Asia",[130,17003,17004],{"class":197}," Pacific\n",[130,17006,17007],{"class":132,"line":793},[130,17008,16896],{"class":570},[130,17010,17011,17013,17016,17019],{"class":132,"line":798},[130,17012,16901],{"class":570},[130,17014,17015],{"class":197},"  Production",[130,17017,17018],{"class":197}," branch",[130,17020,17021],{"class":180}," (git)\n",[130,17023,17024,17026],{"class":132,"line":806},[130,17025,16918],{"class":570},[130,17027,17028],{"class":197},"  main\n",[130,17030,17031,17034,17037,17040],{"class":132,"line":1073},[130,17032,17033],{"class":570},"✔",[130,17035,17036],{"class":197}," Project",[130,17038,17039],{"class":197}," sample-blog",[130,17041,17042],{"class":197}," created\n",[130,17044,17045,17047,17050,17052,17055],{"class":132,"line":1086},[130,17046,17033],{"class":570},[130,17048,17049],{"class":197}," Connected",[130,17051,16910],{"class":197},[130,17053,17054],{"class":197}," tsukiyama-3",[130,17056,17057],{"class":197}," team.\n",[130,17059,17060,17062,17065,17067,17069],{"class":132,"line":1092},[130,17061,17033],{"class":570},[130,17063,17064],{"class":197}," Linked",[130,17066,16910],{"class":197},[130,17068,17039],{"class":197},[130,17070,17071],{"class":197}," project.\n",[16,17073,17074,17075,17077],{},"問題なければビルドが走ります。",[35,17076],{},"\nビルドに成功するとデプロイ先の URL が表示されるのでアクセスしてみましょう。",[16,17079,17080],{},[2692,17081],{"alt":92,"src":17082},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1743348385/tsukiyama-blog/nuxt-content-v3-blog/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-03-31_0.26.01_kws1ic.png",[16,17084,17085,17086],{},"Welcome ページが表示されていたら完了です。",[35,17087],{},[11,17089,17090],{"id":17090},"実装",[16,17092,17093],{},"環境構築も終えたのでいよいよ実装に入っていきます。",[76,17095,17096],{"id":17096},"コレクション定義",[16,17098,17099,17100,17102,17103,17106],{},"v3 では従来のファイルベースの管理から SQL のデータベースシステムに移行しました。",[35,17101],{},"\nファイル管理の方法が変わったからといって内部でいい感じに ",[90,17104,17105],{},".sqlite"," ファイルを生成してくれているので使う際に特に意識する必要はないと思います。",[2523,17108],{"url":17109},"https://content.nuxt.com/docs/files/markdown",[16,17111,17112,17113,17115],{},"Nuxt Content v3 ではコレクションを定義してコンテンツを管理します。",[35,17114],{},"\nコレクションとは、関連するコンテンツのグループです。",[16,17117,17118,17119,17121,17122,17124,16674],{},"コレクションの定義は",[90,17120,125],{},"で行います。",[35,17123],{},[90,17125,125],{},[16,17127,17128],{},"コレクションには任意でスキーマの定義もできます。",[83,17130,17132],{"className":123,"code":17131,"filename":125,"language":126,"meta":92,"style":92},"import { defineContentConfig, defineCollection, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    blog: defineCollection({\n      type: \"page\",\n      source: \"blog/*.md\",\n      // スキーマ定義\n      schema: z.object({\n        title: z.string(),\n        description: z.string(),\n        image: z.string(),\n        published: z.boolean(),\n      })\n    }),\n  },\n})\n",[90,17133,17134,17160,17164,17176,17184,17197,17211,17226,17231,17247,17263,17279,17296,17314,17320,17328,17334],{"__ignoreMap":92},[130,17135,17136,17138,17140,17142,17144,17146,17148,17150,17152,17154,17156,17158],{"class":132,"line":133},[130,17137,493],{"class":136},[130,17139,499],{"class":162},[130,17141,144],{"class":180},[130,17143,325],{"class":162},[130,17145,177],{"class":180},[130,17147,325],{"class":162},[130,17149,232],{"class":180},[130,17151,505],{"class":162},[130,17153,508],{"class":136},[130,17155,194],{"class":193},[130,17157,874],{"class":197},[130,17159,515],{"class":193},[130,17161,17162],{"class":132,"line":155},[130,17163,420],{"emptyLinePlaceholder":419},[130,17165,17166,17168,17170,17172,17174],{"class":132,"line":169},[130,17167,137],{"class":136},[130,17169,140],{"class":136},[130,17171,144],{"class":143},[130,17173,148],{"class":147},[130,17175,152],{"class":151},[130,17177,17178,17180,17182],{"class":132,"line":185},[130,17179,159],{"class":158},[130,17181,163],{"class":162},[130,17183,166],{"class":162},[130,17185,17186,17189,17191,17193,17195],{"class":132,"line":207},[130,17187,17188],{"class":158},"    blog",[130,17190,163],{"class":162},[130,17192,177],{"class":143},[130,17194,148],{"class":180},[130,17196,152],{"class":162},[130,17198,17199,17201,17203,17205,17207,17209],{"class":132,"line":224},[130,17200,188],{"class":158},[130,17202,163],{"class":162},[130,17204,11687],{"class":193},[130,17206,198],{"class":197},[130,17208,2163],{"class":193},[130,17210,204],{"class":162},[130,17212,17213,17215,17217,17219,17222,17224],{"class":132,"line":245},[130,17214,210],{"class":158},[130,17216,163],{"class":162},[130,17218,11687],{"class":193},[130,17220,17221],{"class":197},"blog/*.md",[130,17223,2163],{"class":193},[130,17225,204],{"class":162},[130,17227,17228],{"class":132,"line":265},[130,17229,17230],{"class":328},"      // スキーマ定義\n",[130,17232,17233,17235,17237,17239,17241,17243,17245],{"class":132,"line":283},[130,17234,227],{"class":158},[130,17236,163],{"class":162},[130,17238,232],{"class":180},[130,17240,235],{"class":162},[130,17242,238],{"class":143},[130,17244,148],{"class":180},[130,17246,152],{"class":162},[130,17248,17249,17251,17253,17255,17257,17259,17261],{"class":132,"line":302},[130,17250,248],{"class":158},[130,17252,163],{"class":162},[130,17254,232],{"class":180},[130,17256,235],{"class":162},[130,17258,257],{"class":143},[130,17260,260],{"class":180},[130,17262,204],{"class":162},[130,17264,17265,17267,17269,17271,17273,17275,17277],{"class":132,"line":332},[130,17266,268],{"class":158},[130,17268,163],{"class":162},[130,17270,232],{"class":180},[130,17272,235],{"class":162},[130,17274,257],{"class":143},[130,17276,260],{"class":180},[130,17278,204],{"class":162},[130,17280,17281,17284,17286,17288,17290,17292,17294],{"class":132,"line":341},[130,17282,17283],{"class":158},"        image",[130,17285,163],{"class":162},[130,17287,232],{"class":180},[130,17289,235],{"class":162},[130,17291,257],{"class":143},[130,17293,260],{"class":180},[130,17295,204],{"class":162},[130,17297,17298,17301,17303,17305,17307,17310,17312],{"class":132,"line":349},[130,17299,17300],{"class":158},"        published",[130,17302,163],{"class":162},[130,17304,232],{"class":180},[130,17306,235],{"class":162},[130,17308,17309],{"class":143},"boolean",[130,17311,260],{"class":180},[130,17313,204],{"class":162},[130,17315,17316,17318],{"class":132,"line":355},[130,17317,335],{"class":162},[130,17319,338],{"class":180},[130,17321,17322,17324,17326],{"class":132,"line":783},[130,17323,344],{"class":162},[130,17325,584],{"class":180},[130,17327,204],{"class":162},[130,17329,17330,17332],{"class":132,"line":793},[130,17331,1981],{"class":162},[130,17333,204],{"class":151},[130,17335,17336,17338],{"class":132,"line":798},[130,17337,358],{"class":151},[130,17339,338],{"class":147},[76,17341,17342],{"id":17342},"コンテンツ作成",[16,17344,17345,17346,17349,17350,17352,17353,17356],{},"コンテンツはルート直下に",[90,17347,17348],{},"/content","を作成して管理します。",[35,17351],{},"\nためしに",[90,17354,17355],{},"~/content/blog/","配下にいくつか以下のようにマークダウンファイルを作成してみます。",[83,17358,17361],{"className":378,"code":17359,"filename":17360,"language":381,"meta":92,"style":92},"---\ntitle: 4月1日の記事\ndescription: 4月1日の記事です。\nimage: https://picsum.photos/584/328\npublished: true\n---\n\n# タイトル\n\nパラグラフ\n","content/blog/0401.md",[90,17362,17363,17367,17372,17377,17382,17387,17391,17395,17404,17408],{"__ignoreMap":92},[130,17364,17365],{"class":132,"line":133},[130,17366,389],{"class":388},[130,17368,17369],{"class":132,"line":155},[130,17370,17371],{"class":180},"title: 4月1日の記事\n",[130,17373,17374],{"class":132,"line":169},[130,17375,17376],{"class":180},"description: 4月1日の記事です。\n",[130,17378,17379],{"class":132,"line":185},[130,17380,17381],{"class":180},"image: https://picsum.photos/584/328\n",[130,17383,17384],{"class":132,"line":207},[130,17385,17386],{"class":180},"published: true\n",[130,17388,17389],{"class":132,"line":224},[130,17390,389],{"class":414},[130,17392,17393],{"class":132,"line":245},[130,17394,420],{"emptyLinePlaceholder":419},[130,17396,17397,17400],{"class":132,"line":265},[130,17398,17399],{"class":414},"# ",[130,17401,17403],{"class":17402},"sDalj","タイトル\n",[130,17405,17406],{"class":132,"line":283},[130,17407,420],{"emptyLinePlaceholder":419},[130,17409,17410],{"class":132,"line":302},[130,17411,17412],{"class":180},"パラグラフ\n",[76,17414,17416],{"id":17415},"top-ページ","TOP ページ",[16,17418,17419,6987],{},[90,17420,17421],{},"~/pages/index",[83,17423,17426],{"className":2137,"code":17424,"filename":17425,"language":2140,"meta":92,"style":92},"\u003Cscript setup lang=\"ts\">\nconst { data } = await useAsyncData('blog', () =>\n  queryCollection('blog').all(),\n)\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cul class=\"space-y-8\">\n      \u003Cli\n        v-for=\"article in data\"\n        :key=\"article.path\"\n        class=\"list-none divide-y divide-gray-300 hover:opacity-70\"\n      >\n        \u003CNuxtLink\n          :to=\"article.path\"\n          class=\"gap-x-4\"\n        >\n          \u003Cdiv class=\"space-y-1 text-blue-600 underline\">\n            \u003Ch3 class=\"text-base md:text-xl font-bold\">{{ article.title }}\u003C/h3>\n            \u003Cp class=\"text-sm md:text-base opacity-80\">\n              {{ article.description }}\n            \u003C/p>\n          \u003C/div>\n        \u003C/NuxtLink>\n      \u003C/li>\n    \u003C/ul>\n  \u003C/div>\n\u003C/template>\n","pages/index.vue",[90,17427,17428,17448,17480,17503,17507,17515,17519,17527,17535,17554,17561,17575,17589,17602,17606,17613,17626,17640,17645,17664,17693,17712,17717,17726,17735,17744,17752,17760,17768],{"__ignoreMap":92},[130,17429,17430,17432,17434,17436,17438,17440,17442,17444,17446],{"class":132,"line":133},[130,17431,608],{"class":162},[130,17433,5698],{"class":2149},[130,17435,2154],{"class":2153},[130,17437,2157],{"class":2153},[130,17439,2160],{"class":162},[130,17441,2163],{"class":193},[130,17443,126],{"class":197},[130,17445,2163],{"class":193},[130,17447,2170],{"class":162},[130,17449,17450,17452,17454,17456,17458,17460,17462,17464,17466,17468,17471,17473,17475,17477],{"class":132,"line":155},[130,17451,1012],{"class":546},[130,17453,499],{"class":162},[130,17455,1926],{"class":597},[130,17457,505],{"class":162},[130,17459,555],{"class":554},[130,17461,603],{"class":136},[130,17463,14802],{"class":143},[130,17465,148],{"class":180},[130,17467,201],{"class":193},[130,17469,17470],{"class":197},"blog",[130,17472,201],{"class":193},[130,17474,325],{"class":162},[130,17476,1912],{"class":162},[130,17478,17479],{"class":546}," =>\n",[130,17481,17482,17485,17487,17489,17491,17493,17495,17497,17499,17501],{"class":132,"line":169},[130,17483,17484],{"class":143},"  queryCollection",[130,17486,148],{"class":180},[130,17488,201],{"class":193},[130,17490,17470],{"class":197},[130,17492,201],{"class":193},[130,17494,584],{"class":180},[130,17496,235],{"class":162},[130,17498,788],{"class":143},[130,17500,260],{"class":180},[130,17502,204],{"class":162},[130,17504,17505],{"class":132,"line":185},[130,17506,338],{"class":180},[130,17508,17509,17511,17513],{"class":132,"line":207},[130,17510,2193],{"class":162},[130,17512,5698],{"class":2149},[130,17514,2170],{"class":162},[130,17516,17517],{"class":132,"line":224},[130,17518,420],{"emptyLinePlaceholder":419},[130,17520,17521,17523,17525],{"class":132,"line":245},[130,17522,608],{"class":162},[130,17524,2130],{"class":2149},[130,17526,2170],{"class":162},[130,17528,17529,17531,17533],{"class":132,"line":265},[130,17530,2989],{"class":162},[130,17532,2683],{"class":2149},[130,17534,2170],{"class":162},[130,17536,17537,17539,17541,17543,17545,17547,17550,17552],{"class":132,"line":283},[130,17538,3010],{"class":162},[130,17540,2566],{"class":2149},[130,17542,2973],{"class":2153},[130,17544,2160],{"class":162},[130,17546,2163],{"class":193},[130,17548,17549],{"class":197},"space-y-8",[130,17551,2163],{"class":193},[130,17553,2170],{"class":162},[130,17555,17556,17558],{"class":132,"line":302},[130,17557,3030],{"class":162},[130,17559,17560],{"class":2149},"li\n",[130,17562,17563,17566,17568,17570,17573],{"class":132,"line":332},[130,17564,17565],{"class":2153},"        v-for",[130,17567,2160],{"class":162},[130,17569,2163],{"class":193},[130,17571,17572],{"class":197},"article in data",[130,17574,2789],{"class":193},[130,17576,17577,17580,17582,17584,17587],{"class":132,"line":341},[130,17578,17579],{"class":2153},"        :key",[130,17581,2160],{"class":162},[130,17583,2163],{"class":193},[130,17585,17586],{"class":197},"article.path",[130,17588,2789],{"class":193},[130,17590,17591,17593,17595,17597,17600],{"class":132,"line":349},[130,17592,10977],{"class":2153},[130,17594,2160],{"class":162},[130,17596,2163],{"class":193},[130,17598,17599],{"class":197},"list-none divide-y divide-gray-300 hover:opacity-70",[130,17601,2789],{"class":193},[130,17603,17604],{"class":132,"line":355},[130,17605,10991],{"class":162},[130,17607,17608,17610],{"class":132,"line":783},[130,17609,10996],{"class":162},[130,17611,17612],{"class":2149},"NuxtLink\n",[130,17614,17615,17618,17620,17622,17624],{"class":132,"line":793},[130,17616,17617],{"class":2153},"          :to",[130,17619,2160],{"class":162},[130,17621,2163],{"class":193},[130,17623,17586],{"class":197},[130,17625,2789],{"class":193},[130,17627,17628,17631,17633,17635,17638],{"class":132,"line":798},[130,17629,17630],{"class":2153},"          class",[130,17632,2160],{"class":162},[130,17634,2163],{"class":193},[130,17636,17637],{"class":197},"gap-x-4",[130,17639,2789],{"class":193},[130,17641,17642],{"class":132,"line":806},[130,17643,17644],{"class":162},"        >\n",[130,17646,17647,17649,17651,17653,17655,17657,17660,17662],{"class":132,"line":1073},[130,17648,11053],{"class":162},[130,17650,2683],{"class":2149},[130,17652,2973],{"class":2153},[130,17654,2160],{"class":162},[130,17656,2163],{"class":193},[130,17658,17659],{"class":197},"space-y-1 text-blue-600 underline",[130,17661,2163],{"class":193},[130,17663,2170],{"class":162},[130,17665,17666,17669,17671,17673,17675,17677,17680,17682,17684,17687,17689,17691],{"class":132,"line":1086},[130,17667,17668],{"class":162},"            \u003C",[130,17670,76],{"class":2149},[130,17672,2973],{"class":2153},[130,17674,2160],{"class":162},[130,17676,2163],{"class":193},[130,17678,17679],{"class":197},"text-base md:text-xl font-bold",[130,17681,2163],{"class":193},[130,17683,618],{"class":162},[130,17685,17686],{"class":180},"{{ article.title }}",[130,17688,2193],{"class":162},[130,17690,76],{"class":2149},[130,17692,2170],{"class":162},[130,17694,17695,17697,17699,17701,17703,17705,17708,17710],{"class":132,"line":1092},[130,17696,17668],{"class":162},[130,17698,16],{"class":2149},[130,17700,2973],{"class":2153},[130,17702,2160],{"class":162},[130,17704,2163],{"class":193},[130,17706,17707],{"class":197},"text-sm md:text-base opacity-80",[130,17709,2163],{"class":193},[130,17711,2170],{"class":162},[130,17713,17714],{"class":132,"line":1128},[130,17715,17716],{"class":180},"              {{ article.description }}\n",[130,17718,17719,17722,17724],{"class":132,"line":1151},[130,17720,17721],{"class":162},"            \u003C/",[130,17723,16],{"class":2149},[130,17725,2170],{"class":162},[130,17727,17728,17731,17733],{"class":132,"line":1156},[130,17729,17730],{"class":162},"          \u003C/",[130,17732,2683],{"class":2149},[130,17734,2170],{"class":162},[130,17736,17737,17739,17742],{"class":132,"line":1179},[130,17738,11126],{"class":162},[130,17740,17741],{"class":2149},"NuxtLink",[130,17743,2170],{"class":162},[130,17745,17746,17748,17750],{"class":132,"line":1188},[130,17747,11135],{"class":162},[130,17749,2569],{"class":2149},[130,17751,2170],{"class":162},[130,17753,17754,17756,17758],{"class":132,"line":1193},[130,17755,3042],{"class":162},[130,17757,2566],{"class":2149},[130,17759,2170],{"class":162},[130,17761,17762,17764,17766],{"class":132,"line":1198},[130,17763,3051],{"class":162},[130,17765,2683],{"class":2149},[130,17767,2170],{"class":162},[130,17769,17770,17772,17774],{"class":132,"line":1222},[130,17771,2193],{"class":162},[130,17773,2130],{"class":2149},[130,17775,2170],{"class":162},[16,17777,17778,17779,17781,17782,17784,17787,17788,17790],{},"コンテンツの取得は",[90,17780,814],{},"を用います。",[35,17783],{},[90,17785,17786],{},"published","が",[90,17789,6945],{},"の記事を取得するように絞り込んでいます。",[2523,17792],{"url":17793},"https://content.nuxt.com/docs/utils/query-collection",[16,17795,17796,17799],{},[90,17797,17798],{},"app.vue","も修正します。",[83,17801,17803],{"className":2137,"code":17802,"filename":17798,"language":2140,"meta":92,"style":92},"\u003Ctemplate>\n  \u003Cdiv>\n    \u003CNuxtPage />\n  \u003C/div>\n\u003C/template>\n",[90,17804,17805,17813,17821,17830,17838],{"__ignoreMap":92},[130,17806,17807,17809,17811],{"class":132,"line":133},[130,17808,608],{"class":162},[130,17810,2130],{"class":2149},[130,17812,2170],{"class":162},[130,17814,17815,17817,17819],{"class":132,"line":155},[130,17816,2989],{"class":162},[130,17818,2683],{"class":2149},[130,17820,2170],{"class":162},[130,17822,17823,17825,17828],{"class":132,"line":169},[130,17824,3010],{"class":162},[130,17826,17827],{"class":2149},"NuxtPage",[130,17829,6269],{"class":162},[130,17831,17832,17834,17836],{"class":132,"line":185},[130,17833,3051],{"class":162},[130,17835,2683],{"class":2149},[130,17837,2170],{"class":162},[130,17839,17840,17842,17844],{"class":132,"line":207},[130,17841,2193],{"class":162},[130,17843,2130],{"class":2149},[130,17845,2170],{"class":162},[16,17847,17848,17849,17851],{},"画面確認すると",[90,17850,17348],{},"配下に配置した記事が表示されていると思います。",[16,17853,17854],{},[2692,17855],{"alt":92,"src":17856},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1743910602/tsukiyama-blog/nuxt-content-v3-blog/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-04-06_12.30.49_zljzpx.png",[76,17858,17859],{"id":17859},"記事ページ",[16,17861,17862,17863,6987],{},"記事ページとして",[90,17864,17865],{},"pages/blog/[...slug]/index.vue",[83,17867,17869],{"className":2137,"code":17868,"language":2140,"meta":92,"style":92},"\u003C!-- pages/blog/[...slug]/index.vue -->\n\u003Cscript setup lang=\"ts\">\nconst route = useRoute()\nconst { data } = await useAsyncData(route.path, () =>\n  queryCollection('blog').path(route.path).first(),\n)\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"max-w-[800px] mx-auto\">\n    \u003Carticle\n      v-if=\"data\"\n      id=\"article\"\n      class=\"space-y-12\"\n    >\n      \u003Cdiv class=\"space-y-4\">\n        \u003Cimg\n          ref=\"image\"\n          :src=\"data.image\"\n          alt=\"\"\n          width=\"584\"\n          height=\"328\"\n          class=\"mx-auto\"\n        >\n        \u003Ch1 class=\"font-bold text-xl md:text-3xl\">\n          {{ data.title }}\n        \u003C/h1>\n        \u003Cp class=\"opacity-80 text-sm md:text-base\">\n          {{ data.description }}\n        \u003C/p>\n      \u003C/div>\n      \u003CContentRenderer\n        :value=\"data\"\n        class=\"space-y-8\"\n      />\n    \u003C/article>\n    \u003Cdiv v-else>\n      \u003Ch1>記事が見つかりませんでした\u003C/h1>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n",[90,17870,17871,17876,17896,17908,17937,17970,17974,17982,17986,17994,18013,18020,18033,18046,18059,18063,18082,18088,18101,18115,18124,18138,18152,18164,18168,18188,18193,18201,18220,18225,18233,18241,18248,18261,18273,18278,18286,18297,18314,18322,18330],{"__ignoreMap":92},[130,17872,17873],{"class":132,"line":133},[130,17874,17875],{"class":328},"\u003C!-- pages/blog/[...slug]/index.vue -->\n",[130,17877,17878,17880,17882,17884,17886,17888,17890,17892,17894],{"class":132,"line":155},[130,17879,608],{"class":162},[130,17881,5698],{"class":2149},[130,17883,2154],{"class":2153},[130,17885,2157],{"class":2153},[130,17887,2160],{"class":162},[130,17889,2163],{"class":193},[130,17891,126],{"class":197},[130,17893,2163],{"class":193},[130,17895,2170],{"class":162},[130,17897,17898,17900,17902,17904,17906],{"class":132,"line":169},[130,17899,1012],{"class":546},[130,17901,2261],{"class":597},[130,17903,555],{"class":554},[130,17905,2266],{"class":143},[130,17907,669],{"class":180},[130,17909,17910,17912,17914,17916,17918,17920,17922,17924,17927,17929,17931,17933,17935],{"class":132,"line":185},[130,17911,1012],{"class":546},[130,17913,499],{"class":162},[130,17915,1926],{"class":597},[130,17917,505],{"class":162},[130,17919,555],{"class":554},[130,17921,603],{"class":136},[130,17923,14802],{"class":143},[130,17925,17926],{"class":180},"(route",[130,17928,235],{"class":162},[130,17930,640],{"class":180},[130,17932,325],{"class":162},[130,17934,1912],{"class":162},[130,17936,17479],{"class":546},[130,17938,17939,17941,17943,17945,17947,17949,17951,17953,17955,17957,17959,17962,17964,17966,17968],{"class":132,"line":207},[130,17940,17484],{"class":143},[130,17942,148],{"class":180},[130,17944,201],{"class":193},[130,17946,17470],{"class":197},[130,17948,201],{"class":193},[130,17950,584],{"class":180},[130,17952,235],{"class":162},[130,17954,640],{"class":143},[130,17956,17926],{"class":180},[130,17958,235],{"class":162},[130,17960,17961],{"class":180},"path)",[130,17963,235],{"class":162},[130,17965,666],{"class":143},[130,17967,260],{"class":180},[130,17969,204],{"class":162},[130,17971,17972],{"class":132,"line":224},[130,17973,338],{"class":180},[130,17975,17976,17978,17980],{"class":132,"line":245},[130,17977,2193],{"class":162},[130,17979,5698],{"class":2149},[130,17981,2170],{"class":162},[130,17983,17984],{"class":132,"line":265},[130,17985,420],{"emptyLinePlaceholder":419},[130,17987,17988,17990,17992],{"class":132,"line":283},[130,17989,608],{"class":162},[130,17991,2130],{"class":2149},[130,17993,2170],{"class":162},[130,17995,17996,17998,18000,18002,18004,18006,18009,18011],{"class":132,"line":302},[130,17997,2989],{"class":162},[130,17999,2683],{"class":2149},[130,18001,2973],{"class":2153},[130,18003,2160],{"class":162},[130,18005,2163],{"class":193},[130,18007,18008],{"class":197},"max-w-[800px] mx-auto",[130,18010,2163],{"class":193},[130,18012,2170],{"class":162},[130,18014,18015,18017],{"class":132,"line":332},[130,18016,3010],{"class":162},[130,18018,18019],{"class":2149},"article\n",[130,18021,18022,18025,18027,18029,18031],{"class":132,"line":341},[130,18023,18024],{"class":2153},"      v-if",[130,18026,2160],{"class":162},[130,18028,2163],{"class":193},[130,18030,10854],{"class":197},[130,18032,2789],{"class":193},[130,18034,18035,18038,18040,18042,18044],{"class":132,"line":349},[130,18036,18037],{"class":2153},"      id",[130,18039,2160],{"class":162},[130,18041,2163],{"class":193},[130,18043,1164],{"class":197},[130,18045,2789],{"class":193},[130,18047,18048,18050,18052,18054,18057],{"class":132,"line":355},[130,18049,14556],{"class":2153},[130,18051,2160],{"class":162},[130,18053,2163],{"class":193},[130,18055,18056],{"class":197},"space-y-12",[130,18058,2789],{"class":193},[130,18060,18061],{"class":132,"line":783},[130,18062,14584],{"class":162},[130,18064,18065,18067,18069,18071,18073,18075,18078,18080],{"class":132,"line":793},[130,18066,3030],{"class":162},[130,18068,2683],{"class":2149},[130,18070,2973],{"class":2153},[130,18072,2160],{"class":162},[130,18074,2163],{"class":193},[130,18076,18077],{"class":197},"space-y-4",[130,18079,2163],{"class":193},[130,18081,2170],{"class":162},[130,18083,18084,18086],{"class":132,"line":798},[130,18085,10996],{"class":162},[130,18087,2774],{"class":2149},[130,18089,18090,18093,18095,18097,18099],{"class":132,"line":806},[130,18091,18092],{"class":2153},"          ref",[130,18094,2160],{"class":162},[130,18096,2163],{"class":193},[130,18098,3935],{"class":197},[130,18100,2789],{"class":193},[130,18102,18103,18106,18108,18110,18113],{"class":132,"line":1073},[130,18104,18105],{"class":2153},"          :src",[130,18107,2160],{"class":162},[130,18109,2163],{"class":193},[130,18111,18112],{"class":197},"data.image",[130,18114,2789],{"class":193},[130,18116,18117,18120,18122],{"class":132,"line":1086},[130,18118,18119],{"class":2153},"          alt",[130,18121,2160],{"class":162},[130,18123,3384],{"class":193},[130,18125,18126,18129,18131,18133,18136],{"class":132,"line":1092},[130,18127,18128],{"class":2153},"          width",[130,18130,2160],{"class":162},[130,18132,2163],{"class":193},[130,18134,18135],{"class":197},"584",[130,18137,2789],{"class":193},[130,18139,18140,18143,18145,18147,18150],{"class":132,"line":1128},[130,18141,18142],{"class":2153},"          height",[130,18144,2160],{"class":162},[130,18146,2163],{"class":193},[130,18148,18149],{"class":197},"328",[130,18151,2789],{"class":193},[130,18153,18154,18156,18158,18160,18162],{"class":132,"line":1151},[130,18155,17630],{"class":2153},[130,18157,2160],{"class":162},[130,18159,2163],{"class":193},[130,18161,2687],{"class":197},[130,18163,2789],{"class":193},[130,18165,18166],{"class":132,"line":1156},[130,18167,17644],{"class":162},[130,18169,18170,18172,18175,18177,18179,18181,18184,18186],{"class":132,"line":1179},[130,18171,10996],{"class":162},[130,18173,18174],{"class":2149},"h1",[130,18176,2973],{"class":2153},[130,18178,2160],{"class":162},[130,18180,2163],{"class":193},[130,18182,18183],{"class":197},"font-bold text-xl md:text-3xl",[130,18185,2163],{"class":193},[130,18187,2170],{"class":162},[130,18189,18190],{"class":132,"line":1188},[130,18191,18192],{"class":180},"          {{ data.title }}\n",[130,18194,18195,18197,18199],{"class":132,"line":1193},[130,18196,11126],{"class":162},[130,18198,18174],{"class":2149},[130,18200,2170],{"class":162},[130,18202,18203,18205,18207,18209,18211,18213,18216,18218],{"class":132,"line":1198},[130,18204,10996],{"class":162},[130,18206,16],{"class":2149},[130,18208,2973],{"class":2153},[130,18210,2160],{"class":162},[130,18212,2163],{"class":193},[130,18214,18215],{"class":197},"opacity-80 text-sm md:text-base",[130,18217,2163],{"class":193},[130,18219,2170],{"class":162},[130,18221,18222],{"class":132,"line":1222},[130,18223,18224],{"class":180},"          {{ data.description }}\n",[130,18226,18227,18229,18231],{"class":132,"line":1227},[130,18228,11126],{"class":162},[130,18230,16],{"class":2149},[130,18232,2170],{"class":162},[130,18234,18235,18237,18239],{"class":132,"line":1232},[130,18236,11135],{"class":162},[130,18238,2683],{"class":2149},[130,18240,2170],{"class":162},[130,18242,18243,18245],{"class":132,"line":1237},[130,18244,3030],{"class":162},[130,18246,18247],{"class":2149},"ContentRenderer\n",[130,18249,18250,18253,18255,18257,18259],{"class":132,"line":1243},[130,18251,18252],{"class":2153},"        :value",[130,18254,2160],{"class":162},[130,18256,2163],{"class":193},[130,18258,10854],{"class":197},[130,18260,2789],{"class":193},[130,18262,18263,18265,18267,18269,18271],{"class":132,"line":1256},[130,18264,10977],{"class":2153},[130,18266,2160],{"class":162},[130,18268,2163],{"class":193},[130,18270,17549],{"class":197},[130,18272,2789],{"class":193},[130,18274,18275],{"class":132,"line":1268},[130,18276,18277],{"class":162},"      />\n",[130,18279,18280,18282,18284],{"class":132,"line":1273},[130,18281,3042],{"class":162},[130,18283,1164],{"class":2149},[130,18285,2170],{"class":162},[130,18287,18288,18290,18292,18295],{"class":132,"line":1301},[130,18289,3010],{"class":162},[130,18291,2683],{"class":2149},[130,18293,18294],{"class":2153}," v-else",[130,18296,2170],{"class":162},[130,18298,18299,18301,18303,18305,18308,18310,18312],{"class":132,"line":1320},[130,18300,3030],{"class":162},[130,18302,18174],{"class":2149},[130,18304,618],{"class":162},[130,18306,18307],{"class":180},"記事が見つかりませんでした",[130,18309,2193],{"class":162},[130,18311,18174],{"class":2149},[130,18313,2170],{"class":162},[130,18315,18316,18318,18320],{"class":132,"line":1325},[130,18317,3042],{"class":162},[130,18319,2683],{"class":2149},[130,18321,2170],{"class":162},[130,18323,18324,18326,18328],{"class":132,"line":1344},[130,18325,3051],{"class":162},[130,18327,2683],{"class":2149},[130,18329,2170],{"class":162},[130,18331,18332,18334,18336],{"class":132,"line":1349},[130,18333,2193],{"class":162},[130,18335,2130],{"class":2149},[130,18337,2170],{"class":162},[16,18339,18340],{},"画面を確認してみるとマークダウンで書いた記事が表示されていると思います。",[16,18342,18343],{},[2692,18344],{"alt":92,"src":18345},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1743910601/tsukiyama-blog/nuxt-content-v3-blog/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-04-06_12.36.23_u4jfrf.png",[11,18347,18348],{"id":18348},"公開する",[16,18350,18351,18352,18354,18355,18357,18359],{},"Nuxt Hub のダッシューボードから Git リポジトリを紐づけることによって、",[90,18353,2970],{},"ブランチにpushするだけでデプロイできるようになります。簡単ですね。",[35,18356],{},[90,18358,2970],{},"ではないブランチにpushするとプレビュー環境が作られます。嬉しいですね。",[16,18361,18362,18365,18366,18365,18369,18365,18372,18365,18375,18365,18378],{},[90,18363,18364],{},"ダッシュボード"," > ",[90,18367,18368],{},"該当プロジェクト",[90,18370,18371],{},"Settings",[90,18373,18374],{},"General",[90,18376,18377],{},"Git repository",[90,18379,18380],{},"Link repository",[16,18382,18383],{},[2692,18384],{"alt":92,"src":18385},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1743914270/tsukiyama-blog/nuxt-content-v3-blog/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2025-04-06_13.32.34_nl65ye.png",[16,18387,18388],{},"（Nuxt Content を Cloudflare Pages にホスティングする場合は、D1データベースに紐付ける必要があるのですが、その辺は Nuxt Hub がいい感じにしてくれているっぽいです。）",[11,18390,9663],{"id":9663},[16,18392,18393,18394,18397],{},"本記事では",[106,18395,18396],{},"Nuxt Contentを使って爆速で個人ブログを作る","ことをテーマになるべく寄り道をせずに最低限のステップだけを紹介しました。",[16,18399,18400],{},"細かい機能やUIについてはご自身の好みでカスタマイズしていってください。",[16,18402,18403,18404,18406,18407,18409],{},"本ブログのコードは公開しています。",[35,18405],{},"\n本記事で実装しているコードとは一部異なりますが気になる箇所があればご覧ください。",[35,18408],{},"\n（誤字脱字や内容の誤りなどがありましたらコメントやIssueを建てていただけるとありがたいです。）",[2523,18411],{"url":18412},"https://github.com/tsukiyama-3/tsukiyama-blog",[16,18414,18415],{},"今後も主にフロントエンドにまつわる記事を書いていく予定ですので、お見知り置きを。",[2420,18417,18418],{},"html pre.shiki code .sywW5, html code.shiki .sywW5{--shiki-light:#E2931D;--shiki-default:#FFB757;--shiki-dark:#B392F0}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sFoIN, html code.shiki .sFoIN{--shiki-light:#6182B8;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sipQf, html code.shiki .sipQf{--shiki-light:#90A4AE;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sfFde, html code.shiki .sfFde{--shiki-light:#39ADB5;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sZPSj, html code.shiki .sZPSj{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#BDC4CC;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sDE9X, html code.shiki .sDE9X{--shiki-light:#90A4AE;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sdaUG, html code.shiki .sdaUG{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sDalj, html code.shiki .sDalj{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .siCa7, html code.shiki .siCa7{--shiki-light:#E53935;--shiki-default:#72F088;--shiki-dark:#85E89D}html pre.shiki code .sOohs, html code.shiki .sOohs{--shiki-light:#9C3EDA;--shiki-default:#91CBFF;--shiki-dark:#B392F0}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sSuNx, html code.shiki .sSuNx{--shiki-light:#90A4AE;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sUBcA, html code.shiki .sUBcA{--shiki-light:#39ADB5;--shiki-default:#FF9492;--shiki-dark:#F97583}",{"title":92,"searchDepth":169,"depth":169,"links":18420},[18421,18422,18427,18433,18436,18442,18443],{"id":2464,"depth":155,"text":2464},{"id":16471,"depth":155,"text":16471,"children":18423},[18424,18425,18426],{"id":16486,"depth":169,"text":16487},{"id":16496,"depth":169,"text":16497},{"id":16506,"depth":169,"text":16507},{"id":16516,"depth":155,"text":16516,"children":18428},[18429,18430,18431,18432],{"id":16519,"depth":169,"text":16520},{"id":16593,"depth":169,"text":16594},{"id":16619,"depth":169,"text":16620},{"id":16644,"depth":169,"text":16645},{"id":16801,"depth":155,"text":16801,"children":18434},[18435],{"id":16807,"depth":169,"text":16807},{"id":17090,"depth":155,"text":17090,"children":18437},[18438,18439,18440,18441],{"id":17096,"depth":169,"text":17096},{"id":17342,"depth":169,"text":17342},{"id":17415,"depth":169,"text":17416},{"id":17859,"depth":169,"text":17859},{"id":18348,"depth":155,"text":18348},{"id":9663,"depth":155,"text":9663},"2025-04-08T00:00:00.000Z","2025 年 1 月にリリースされた Nuxt Content v3 とNuxt Hubを使って個人ブログを爆速で作っていきます。",{},"https://res.cloudinary.com/dyoyv8djx/image/upload/v1744039379/tsukiyama-blog/nuxt-content-v3-blog/ogp-nuxt-content_gg1qi7.png",{"title":71,"description":18445},"tech/nuxt-content-v3-blog",[2452,12553,16497,18451],"Tailwind CSS","jOkCMasi3b25di0y381aKE_PXsbdYsJ816zfCQsRZLg",{"id":18454,"title":18455,"body":18456,"date":19042,"description":19043,"extension":381,"icon":19044,"meta":19045,"navigation":419,"ogImage":2455,"path":19046,"published":419,"publishedAt":2455,"seo":19047,"stem":19048,"tags":2455,"updatedAt":2455,"__hash__":19049},"tech/tech/markdown-sample.md","マークダウンサンプル",{"type":8,"value":18457,"toc":19025},[18458,18461,18498,18501,18503,18505,18509,18518,18521,18525,18617,18636,18652,18656,18678,18683,18687,18701,18706,18711,18715,18778,18808,18812,18857,18861,18865,18881,18885,18940,18982,18985,18991,18997,19001,19010,19022],[11,18459,18460],{"id":10025},"Headers",[83,18462,18464],{"className":378,"code":18463,"language":381,"meta":92,"style":92},"## H2\n\n### h3\n\n#### h4\n",[90,18465,18466,18474,18478,18486,18490],{"__ignoreMap":92},[130,18467,18468,18471],{"class":132,"line":133},[130,18469,18470],{"class":414},"## ",[130,18472,18473],{"class":17402},"H2\n",[130,18475,18476],{"class":132,"line":155},[130,18477,420],{"emptyLinePlaceholder":419},[130,18479,18480,18483],{"class":132,"line":169},[130,18481,18482],{"class":414},"### ",[130,18484,18485],{"class":17402},"h3\n",[130,18487,18488],{"class":132,"line":185},[130,18489,420],{"emptyLinePlaceholder":419},[130,18491,18492,18495],{"class":132,"line":207},[130,18493,18494],{"class":414},"#### ",[130,18496,18497],{"class":17402},"h4\n",[11,18499,18500],{"id":11},"H2",[76,18502,76],{"id":76},[1576,18504,1576],{"id":1576},[11,18506,18508],{"id":18507},"paragraph","Paragraph",[83,18510,18512],{"className":378,"code":18511,"language":381,"meta":92,"style":92},"これはパラグラフです。\n",[90,18513,18514],{"__ignoreMap":92},[130,18515,18516],{"class":132,"line":133},[130,18517,18511],{"class":180},[16,18519,18520],{},"これはパラグラフです。",[11,18522,18524],{"id":18523},"lists","Lists",[83,18526,18528],{"className":378,"code":18527,"language":381,"meta":92,"style":92},"- 箇条書き\n- 箇条書き\n  - ネストも掘れるよ\n  - ネストも掘れるよ\n  - ネストも掘れるよ\n- 箇条書き\n\n1. 箇条書き\n2. 箇条書き\n   1. ネストも掘れるよ\n   2. ネストも掘れるよ\n   3. ネストも掘れるよ\n3. 箇条書き\n",[90,18529,18530,18539,18545,18553,18559,18565,18571,18575,18582,18589,18596,18603,18610],{"__ignoreMap":92},[130,18531,18532,18536],{"class":132,"line":133},[130,18533,18535],{"class":18534},"sANdB","-",[130,18537,18538],{"class":180}," 箇条書き\n",[130,18540,18541,18543],{"class":132,"line":155},[130,18542,18535],{"class":18534},[130,18544,18538],{"class":180},[130,18546,18547,18550],{"class":132,"line":169},[130,18548,18549],{"class":18534},"  -",[130,18551,18552],{"class":180}," ネストも掘れるよ\n",[130,18554,18555,18557],{"class":132,"line":185},[130,18556,18549],{"class":18534},[130,18558,18552],{"class":180},[130,18560,18561,18563],{"class":132,"line":207},[130,18562,18549],{"class":18534},[130,18564,18552],{"class":180},[130,18566,18567,18569],{"class":132,"line":224},[130,18568,18535],{"class":18534},[130,18570,18538],{"class":180},[130,18572,18573],{"class":132,"line":245},[130,18574,420],{"emptyLinePlaceholder":419},[130,18576,18577,18580],{"class":132,"line":265},[130,18578,18579],{"class":18534},"1.",[130,18581,18538],{"class":180},[130,18583,18584,18587],{"class":132,"line":283},[130,18585,18586],{"class":18534},"2.",[130,18588,18538],{"class":180},[130,18590,18591,18594],{"class":132,"line":302},[130,18592,18593],{"class":18534},"   1.",[130,18595,18552],{"class":180},[130,18597,18598,18601],{"class":132,"line":332},[130,18599,18600],{"class":18534},"   2.",[130,18602,18552],{"class":180},[130,18604,18605,18608],{"class":132,"line":341},[130,18606,18607],{"class":18534},"   3.",[130,18609,18552],{"class":180},[130,18611,18612,18615],{"class":132,"line":349},[130,18613,18614],{"class":18534},"3.",[130,18616,18538],{"class":180},[2566,18618,18619,18622,18634],{},[2569,18620,18621],{},"箇条書き",[2569,18623,18624,18625],{},"箇条書き\n",[2566,18626,18627,18630,18632],{},[2569,18628,18629],{},"ネストも掘れるよ",[2569,18631,18629],{},[2569,18633,18629],{},[2569,18635,18621],{},[3178,18637,18638,18640,18650],{},[2569,18639,18621],{},[2569,18641,18624,18642],{},[3178,18643,18644,18646,18648],{},[2569,18645,18629],{},[2569,18647,18629],{},[2569,18649,18629],{},[2569,18651,18621],{},[11,18653,18655],{"id":18654},"links","Links",[83,18657,18659],{"className":378,"code":18658,"language":381,"meta":92,"style":92},"[リンクです](https://tsukiyama.blog)\n",[90,18660,18661],{"__ignoreMap":92},[130,18662,18663,18665,18669,18672,18676],{"class":132,"line":133},[130,18664,11535],{"class":162},[130,18666,18668],{"class":18667},"sQmBJ","リンクです",[130,18670,18671],{"class":162},"](",[130,18673,18675],{"class":18674},"sNOS3","https://tsukiyama.blog",[130,18677,338],{"class":162},[16,18679,18680],{},[10492,18681,18668],{"href":18675,"rel":18682},[10496],[11,18684,18686],{"id":18685},"blockquotes","Blockquotes",[83,18688,18690],{"className":378,"code":18689,"language":381,"meta":92,"style":92},"> 引用はこんな感じです。\n",[90,18691,18692],{"__ignoreMap":92},[130,18693,18694,18697],{"class":132,"line":133},[130,18695,618],{"class":18696},"s2elN",[130,18698,18700],{"class":18699},"swCgp"," 引用はこんな感じです。\n",[16413,18702,18703],{},[16,18704,18705],{},"引用はこんな感じです。",[16,18707,18708],{},[106,18709,18710],{},"協調協調",[11,18712,18714],{"id":18713},"tables","Tables",[83,18716,18718],{"className":378,"code":18717,"language":381,"meta":92,"style":92},"| Header 1 | Header 2 |\n| -------- | -------- |\n| Cell 1   | Cell 2   |\n| Cell 3   | Cell 4   |\n",[90,18719,18720,18736,18750,18764],{"__ignoreMap":92},[130,18721,18722,18725,18728,18730,18733],{"class":132,"line":133},[130,18723,18724],{"class":162},"|",[130,18726,18727],{"class":180}," Header 1 ",[130,18729,18724],{"class":162},[130,18731,18732],{"class":180}," Header 2 ",[130,18734,18735],{"class":162},"|\n",[130,18737,18738,18740,18743,18745,18747],{"class":132,"line":155},[130,18739,18724],{"class":162},[130,18741,18742],{"class":162}," --------",[130,18744,2061],{"class":162},[130,18746,18742],{"class":162},[130,18748,18749],{"class":162}," |\n",[130,18751,18752,18754,18757,18759,18762],{"class":132,"line":169},[130,18753,18724],{"class":162},[130,18755,18756],{"class":180}," Cell 1   ",[130,18758,18724],{"class":162},[130,18760,18761],{"class":180}," Cell 2   ",[130,18763,18735],{"class":162},[130,18765,18766,18768,18771,18773,18776],{"class":132,"line":185},[130,18767,18724],{"class":162},[130,18769,18770],{"class":180}," Cell 3   ",[130,18772,18724],{"class":162},[130,18774,18775],{"class":180}," Cell 4   ",[130,18777,18735],{"class":162},[2722,18779,18780,18790],{},[2725,18781,18782],{},[2728,18783,18784,18787],{},[2731,18785,18786],{},"Header 1",[2731,18788,18789],{},"Header 2",[2738,18791,18792,18800],{},[2728,18793,18794,18797],{},[2743,18795,18796],{},"Cell 1",[2743,18798,18799],{},"Cell 2",[2728,18801,18802,18805],{},[2743,18803,18804],{},"Cell 3",[2743,18806,18807],{},"Cell 4",[11,18809,18811],{"id":18810},"inline-code","Inline Code",[83,18813,18815],{"className":378,"code":18814,"language":381,"meta":92,"style":92},"`console.log(\"インラインコード\")`\n\n`error`{color=\"error\"}\n\n`nuxt.config.ts`{lang=\"ts-type\"}\n",[90,18816,18817,18827,18831,18842,18846],{"__ignoreMap":92},[130,18818,18819,18821,18824],{"class":132,"line":133},[130,18820,645],{"class":1170},[130,18822,18823],{"class":5441},"console.log(\"インラインコード\")",[130,18825,18826],{"class":1170},"`\n",[130,18828,18829],{"class":132,"line":155},[130,18830,420],{"emptyLinePlaceholder":419},[130,18832,18833,18835,18837,18839],{"class":132,"line":169},[130,18834,645],{"class":1170},[130,18836,13996],{"class":5441},[130,18838,645],{"class":1170},[130,18840,18841],{"class":180},"{color=\"error\"}\n",[130,18843,18844],{"class":132,"line":185},[130,18845,420],{"emptyLinePlaceholder":419},[130,18847,18848,18850,18852,18854],{"class":132,"line":207},[130,18849,645],{"class":1170},[130,18851,5282],{"class":5441},[130,18853,645],{"class":1170},[130,18855,18856],{"class":180},"{lang=\"ts-type\"}\n",[16,18858,18859],{},[90,18860,18823],{},[16,18862,18863],{},[90,18864,13996],{"color":13996},[16,18866,18867],{},[90,18868,18869,18872,18874,18877,18879],{"className":5500,"language":5501,"style":92},[130,18870,18871],{"class":570},"nuxt",[130,18873,235],{"class":162},[130,18875,18876],{"class":570},"config",[130,18878,235],{"class":162},[130,18880,126],{"class":570},[11,18882,18884],{"id":18883},"code-blocks","Code Blocks",[83,18886,18888],{"className":378,"code":18887,"language":381,"meta":92,"style":92},"```js [file.js]{2}\nexport default () => {\n  console.log(\"コードブロックはこんな感じです\")\n};\n```\n",[90,18889,18890,18900,18912,18931,18935],{"__ignoreMap":92},[130,18891,18892,18896],{"class":132,"line":133},[130,18893,18895],{"class":18894},"sDOc5","```",[130,18897,18899],{"class":18898},"steeu","js [file.js]{2}\n",[130,18901,18902,18904,18906,18908,18910],{"class":132,"line":155},[130,18903,137],{"class":136},[130,18905,140],{"class":136},[130,18907,1912],{"class":151},[130,18909,587],{"class":546},[130,18911,166],{"class":162},[130,18913,18914,18916,18918,18920,18922,18924,18927,18929],{"class":132,"line":169},[130,18915,13695],{"class":180},[130,18917,235],{"class":162},[130,18919,13329],{"class":143},[130,18921,148],{"class":158},[130,18923,2163],{"class":193},[130,18925,18926],{"class":197},"コードブロックはこんな感じです",[130,18928,2163],{"class":193},[130,18930,338],{"class":158},[130,18932,18933],{"class":132,"line":185},[130,18934,10866],{"class":162},[130,18936,18937],{"class":132,"line":207},[130,18938,18939],{"class":18894},"```\n",[83,18941,18945],{"className":13163,"code":18942,"filename":18943,"highlights":18944,"language":13166,"meta":92,"style":92},"export default () => {\n  console.log(\"コードブロックはこんな感じです\")\n};\n","file.js",[155],[90,18946,18947,18959,18978],{"__ignoreMap":92},[130,18948,18949,18951,18953,18955,18957],{"class":132,"line":133},[130,18950,137],{"class":136},[130,18952,140],{"class":136},[130,18954,1912],{"class":151},[130,18956,587],{"class":546},[130,18958,166],{"class":162},[130,18960,18962,18964,18966,18968,18970,18972,18974,18976],{"class":18961,"line":155},[132,6385],[130,18963,13695],{"class":180},[130,18965,235],{"class":162},[130,18967,13329],{"class":143},[130,18969,148],{"class":158},[130,18971,2163],{"class":193},[130,18973,18926],{"class":197},[130,18975,2163],{"class":193},[130,18977,338],{"class":158},[130,18979,18980],{"class":132,"line":169},[130,18981,10866],{"class":162},[11,18983,18984],{"id":3935},"Image",[83,18986,18989],{"className":18987,"code":18988,"language":88},[86],"![サンプル画像](sample.jpg)\n",[90,18990,18988],{"__ignoreMap":92},[16,18992,18993],{},[2692,18994],{"alt":18995,"src":18996},"サンプル画像","https://res.cloudinary.com/dyoyv8djx/image/upload/v1678911095/sample.jpg",[11,18998,19000],{"id":18999},"mdx","MDX",[83,19002,19004],{"className":378,"code":19003,"language":381,"meta":92,"style":92},":div[MDX はこんな感じです]{class=\"font-bold text-blue-100 bg-linear-45 from-indigo-500 via-purple-500 to-pink-500 p-4 rounded-xl\"}\n",[90,19005,19006],{"__ignoreMap":92},[130,19007,19008],{"class":132,"line":133},[130,19009,19003],{"class":180},[2683,19011,19021],{"className":19012},[19013,19014,19015,19016,19017,19018,19019,19020],"font-bold","text-blue-100","bg-linear-45","from-indigo-500","via-purple-500","to-pink-500","p-4","rounded-xl","MDX はこんな感じです",[2420,19023,19024],{},"html pre.shiki code .sywW5, html code.shiki .sywW5{--shiki-light:#E2931D;--shiki-default:#FFB757;--shiki-dark:#B392F0}html pre.shiki code .seLpV, html code.shiki .seLpV{--shiki-light:#39ADB5;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stP2V, html code.shiki .stP2V{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#FF9492;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sfFde, html code.shiki .sfFde{--shiki-light:#39ADB5;--shiki-default:#FFB757;--shiki-dark:#E1E4E8}html pre.shiki code .sGRfs, html code.shiki .sGRfs{--shiki-light:#9C3EDA;--shiki-default:#FF9492;--shiki-dark:#F97583}html pre.shiki code .sdyPO, html code.shiki .sdyPO{--shiki-light:#90A4AE;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .s7KVs, html code.shiki .s7KVs{--shiki-light:#6182B8;--shiki-default:#DBB7FF;--shiki-dark:#B392F0}html pre.shiki code .sLCpo, html code.shiki .sLCpo{--shiki-light:#E53935;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .sPUPB, html code.shiki .sPUPB{--shiki-light:#39ADB5;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sSIes, html code.shiki .sSIes{--shiki-light:#91B859;--shiki-default:#ADDCFF;--shiki-dark:#9ECBFF}html pre.shiki code .sdaUG, html code.shiki .sdaUG{--shiki-light:#39ADB5;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sDalj, html code.shiki .sDalj{--shiki-light:#E2931D;--shiki-light-font-weight:inherit;--shiki-default:#91CBFF;--shiki-default-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold}html pre.shiki code .sANdB, html code.shiki .sANdB{--shiki-light:#39ADB5;--shiki-default:#FFB757;--shiki-dark:#FFAB70}html pre.shiki code .sQmBJ, html code.shiki .sQmBJ{--shiki-light:#91B859;--shiki-light-text-decoration:inherit;--shiki-default:#ADDCFF;--shiki-default-text-decoration:inherit;--shiki-dark:#DBEDFF;--shiki-dark-text-decoration:underline}html pre.shiki code .sNOS3, html code.shiki .sNOS3{--shiki-light:#E53935;--shiki-light-text-decoration:underline;--shiki-default:#F0F3F6;--shiki-default-text-decoration:underline;--shiki-dark:#E1E4E8;--shiki-dark-text-decoration:underline}html pre.shiki code .s2elN, html code.shiki .s2elN{--shiki-light:#FF5370;--shiki-light-font-style:italic;--shiki-default:#72F088;--shiki-default-font-style:inherit;--shiki-dark:#85E89D;--shiki-dark-font-style:inherit}html pre.shiki code .swCgp, html code.shiki .swCgp{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#72F088;--shiki-default-font-style:inherit;--shiki-dark:#85E89D;--shiki-dark-font-style:inherit}html pre.shiki code .s4Pz2, html code.shiki .s4Pz2{--shiki-light:#39ADB5;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .spR0o, html code.shiki .spR0o{--shiki-light:#91B859;--shiki-default:#91CBFF;--shiki-dark:#79B8FF}html pre.shiki code .sDOc5, html code.shiki .sDOc5{--shiki-light:#91B859;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}html pre.shiki code .steeu, html code.shiki .steeu{--shiki-light:#90A4AE90;--shiki-default:#F0F3F6;--shiki-dark:#E1E4E8}",{"title":92,"searchDepth":169,"depth":169,"links":19026},[19027,19028,19033,19034,19035,19036,19037,19038,19039,19040,19041],{"id":10025,"depth":155,"text":18460},{"id":11,"depth":155,"text":18500,"children":19029},[19030],{"id":76,"depth":169,"text":76,"children":19031},[19032],{"id":1576,"depth":185,"text":1576},{"id":18507,"depth":155,"text":18508},{"id":18523,"depth":155,"text":18524},{"id":18654,"depth":155,"text":18655},{"id":18685,"depth":155,"text":18686},{"id":18713,"depth":155,"text":18714},{"id":18810,"depth":155,"text":18811},{"id":18883,"depth":155,"text":18884},{"id":3935,"depth":155,"text":18984},{"id":18999,"depth":155,"text":19000},"2025-04-07T00:00:00.000Z","本ブログのマークダウンサンプルです。","/avatar_gray_xlafck.webp",{},"/tech/markdown-sample",{"title":18455,"description":19043},"tech/markdown-sample","EEh3k6kZyNDyHWRN1o2yBkkyZ2jN6xYP2Yognt-Lj54",{"id":19051,"avatar":13858,"bio":19052,"birthDate":19053,"birthPlace":19054,"extension":5509,"familyName":14853,"givenName":14837,"meta":19057,"stem":19059,"__hash__":19060},"profile/configurations/profile.json","Web Enginner","1999-10-12T00:00:00.000Z",{"country":19055,"prefecture":19056},"japan","tokyo",{"_description":19058},"プロフィール","configurations/profile","kPDEDsSDS6H6GoBp-wJ2wDaLATpt9oMUQYH1ghTlkhI"]