Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Nuxt(SPA)でもOGPしたい/want to render ogp with nuxt ...
Search
果物リン
May 27, 2019
Technology
3.6k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Nuxt(SPA)でもOGPしたい/want to render ogp with nuxt spa mode
ここにSPAモードのプロッジェクトがあります。
OGP?はい、1個設定できますね。
ページごとに設定したい?いったいなにをいっているんだ。
果物リン
May 27, 2019
More Decks by 果物リン
See All by 果物リン
ADDF - ループエンジニアリングするフレームワークを作ったら/I Didn't Set Out to Build Loop Engineering, But ADDF Did
fruitriin
0
200
AIに与える人間らしさを(略)したら600ページの同人誌になった/I kept thinking about making AI more human, more, more, more... wait, when did this become a 600-page doujinshi?
fruitriin
0
150
記憶を高速で思い出す全文検索パフォーマンス・チューニング テクニック/How to make your AI recall, quickly
fruitriin
0
130
入社半年で作った"社内でも使える"ツール集/Everything I Built on the Side in Half a Year
fruitriin
0
140
embodied記憶の依代 聖杯問答/ Vessel of Memory: The Grail Dialogue #embodied_llm
fruitriin
2
240
ClaudeCodeと遠くへいくためのパーミッションルール/Stop Checking, Start Trusting: Claude Code Permission Rules
fruitriin
0
98
Claude Codeと物忘れ / Invitation talk about context - Why Claude Code forget?
fruitriin
0
140
Claude Codeと2つの巻き戻し戦略 / Two Rewind Strategies with Claude Code
fruitriin
0
290
Electron+Vue+Swift=真のデスクトップアプリ / How to create "Really" desktop app using Electron
fruitriin
0
160
Other Decks in Technology
See All in Technology
二歩目のフロントエンド・ウェブアクセシビリティ
camiha
2
640
DGX Spark でどこまでハッキングができるのか?
kash1064
3
1.3k
しろおびから始める!ログ活用の第一歩
shumei_ito
0
950
ブラウザとサーバーから考えるAI時代のフロントエンド監視
shogo4131
3
980
ストレスなくAIと付き合いたい!こんなときどうしてる?
namiki64
3
570
Code for Security プロジェクト紹介 2026年10月
yu23ki14
0
110
Webの常識が通じないHTMLメールのダークモード
teamlab
PRO
0
130
Refining Active Record
shugo
0
160
WasmをRustにする
sansantech
PRO
0
250
M5Stackで作る BLEマウス GPSログの世界
tomokusaba
PRO
0
430
PagerDuty Tech Hub-鳴らすけれど、人は動かない
ezaki
0
180
Classmethod Company Deck
satoshi7
1
710
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
220
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
330
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
600
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
260
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
How to build a perfect <img>
jonoalderson
1
6.1k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
330
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
940
Ethics towards AI in product and experience design
skipperchong
2
430
Transcript
Nuxt(SPA)でも OGPしたい ՌϦϯ@FruitRiin גࣜձࣾΏΊΈ Roppongi.vue #1 2019/05/27
Q. NuxtͰ ϖʔδݸผʹOGPΛ ઃఆ͍ͨ͠Ͱ͢
SSR, UniversalϞʔυ headͰϝλλάઃఆ
Yes! ͦ͏Ͱ͋Δ͖ʂ
ͱ͜ΖͰ ͜͜ʹSPAϞʔυͷ ϓϩδΣΫτ͕͋Γ·͢
ʮͳΜͰSPAϞʔυͳΜ͔͢ʁʯ ʮ༷͔ͩΒɺܦҢΘ͔ΒΜʯ ʮ͍͞Ͱʯ
ΫϥΠΞϯτͷσΟϨ ʮOGPग़ͳ͍ΜͰ͔͢ʁʯ
Ͱ͢ΑͶʔ
͙͵͵͵…… SPA͔ΒUniversalϞʔυͷΓସ͑…… →fetchͰͷwindow objectૢ࡞͕શ໓ Ұ෦ઃܭΓͳ͓͠ ݕূίετܹ૿……
ΫϥΠΞϯτͷΤϯδχΞ ʮNuxtʹ͢લʹExpressͰ HTMLΛվ͟Μ͢Ε ͍͚ΔͷͰʁʯ
ΓɺΓͭ͘Θ͔Δ Θ͔Δ͕……
Nuxt(SPA)でも OGPしたい 闇の魔術に対する防衛術
自己紹介 • ՌϦϯ@FruitRiin • גࣜձࣾΏΊΈ • ·ͳ͘ೖࣾ4ϲ݄ • ϑϩϯτΤϯδχΞɺνʔϜϦʔμʔɺPMʁ •
Vue͍͍ͧʂ
ʮ͍ͬͯ͏ͳΜ͚ͩͲ͞ɺ Ͱ͖Δͱࢥ͏ʁʯ ʮͪΐͬͱௐͯΈ·͠ΐ͏͔ʯ
ʮͰ͖ͦ͏ͳؾ͕͠·͢ʁʯ ʮϚδͰʁʯ
方針:nuxt startしない プロジェクトを目指す • nuxt start͢Δͱαʔόʔ͕ىಈ͢Δ • վ͟Μͷ༨ͳ͠ • expressΛىಈ͢Δapp.js
తͳͷΛͭ͘Δ • nuxt start ͷΘΓʹ node app.js ͢Δ
app.js? • NodeͰಈ͔͢ϓϩάϥϜͱͯ͠ࢦఆ͢ΔϑΝΠϧ • ߏཁ݅ • nuxtΛexpressͷϞδϡʔϧͱͯ͠ॳظԽ • ։ൃϞʔυͷͱ͖ϗοτϦϩʔυ༻ʹϦϏϧυ •
expressʹϦΫΤετ͕དྷͨͱ͖ Nuxt.jsͰϨϯμϦϯά • expressΛࢦఆϙʔτͰػͤ͞Δ
ͳΔ΄Ͳ·ͬͨ͘Θ͔ΒΜ
app.js • ࢀߟจݙ: nuxt.render() https://ja.nuxtjs.org/api/nuxt-render/ • جຊతͳܕͱ্ͯ͠هͷίʔυΛ ͦͷ··ར༻͠·͠ΐ͏
const { Nuxt, Builder } = require('nuxt') const app =
require('express')() const isProd = (process.env.NODE_ENV === 'production') const port = process.env.PORT || 3000 // Nuxt.js ΛΦϓγϣϯͱͱʹΠϯελϯεԽ͢Δ const config = require('./nuxt.config.js') config.dev = !isProd const nuxt = new Nuxt(config) // ͯ͢ͷϧʔτΛ Nuxt.js ͰϨϯμϦϯά͢Δ app.use(nuxt.render) // ϗοτϦϩʔσΟϯά͢Δ։ൃϞʔυͷͱ͖ͷΈϏϧυ͢Δ if (config.dev) { new Builder(nuxt).build() .then(listen) } else { listen() } function listen() { // αʔόʔΛ Listen ͢Δ app.listen(port, '0.0.0.0') console.log('Server listening on `localhost:' + port + '`.') }
ͦ͏͍͏ͷͩͱఘΊͯ͘Ε
備考:create-nuxt-app • Use a custom server framework? ʹ -> express
ͱճ͢Δ • server/index.js Λࣗಈੜͯ͘͠ΕΔʂʂ • ༰ઌఔͷϑΝΠϧͱ֓Ͷಉ͡
HTMLを取得したい • HTMLͷऔಘʹ nuxt.renderRoute() Λ͏ • SPAϞʔυͰ࣮࣭ςϯϓϨʔτ͕औಘͰ͖Δ • ฦΓͷΦϒδΣΫτʹؚ·ΕΔ html
ʹ ϨϯμϦϯά͠Α͏ͱͨ͠HTML͕ೖ͍ͬͯΔ
ಛఆϧʔςΟϯάͷͱ͖ͷΈͷॲཧ • ϧʔςΟϯάͰॲཧΛ͚͍ͨˠapp.get() ͳͲΛ͏ • express ͷgetϝιου • app.get(‘/detail’) ,
app.get(‘/user/:userId’) ͳͲ
const { Nuxt, Builder } = require('nuxt') const app =
require('express')() const isProd = (process.env.NODE_ENV === 'production') const port = process.env.PORT || 3000 // Nuxt.js ΛΦϓγϣϯͱͱʹΠϯελϯεԽ͢Δ const config = require('./nuxt.config.js') config.dev = !isProd const nuxt = new Nuxt(config) // ͯ͢ͷϧʔτΛ Nuxt.js ͰϨϯμϦϯά͢Δ app.use(nuxt.render) // ϗοτϦϩʔσΟϯά͢Δ։ൃϞʔυͷͱ͖ͷΈϏϧυ͢Δ if (config.dev) { new Builder(nuxt).build() .then(listen) } else { listen() } function listen() { // αʔόʔΛ Listen ͢Δ app.listen(port, '0.0.0.0') console.log('Server listening on `localhost:' + port + '`.') } େࣄͦ͏
// Nuxt.js ΛΦϓγϣϯͱͱʹΠϯελϯεԽ͢Δ const config = require('./nuxt.config.js') config.dev = !isProd
const nuxt = new Nuxt(config) // detailͰಛผॲཧ app.get(‘/detail', async (req, res) => { const result = await nuxt.renderRoute('/'); console.log(result.html) }) // ͯ͢ͷϧʔτΛ Nuxt.js ͰϨϯμϦϯά͢Δ app.use(nuxt.render) Ճ͠·ͨ͠ ↑Ͱॲཧ͞Εͳ͚Ε ɹͬͪ͜Ͱॲཧ͢Δ
None
axiosで必要なデータを引っ張る • ͜͜ීஈͱ͋·ΓมΘΒͳ͍ • axios.get() ͳΓͳΜͳΓ
改ざんしてレンダリング • Կߟ͑ͣʹےͰ String.replace() • String.replace(/<meta data-hid=“og:title”.*?>/, 'ʢུʣ') • ஔͨ͠ͷΛ
res.send() ͢Δ
// detailͰಛผॲཧ app.get("/detail", async (req, res) => { const result
= await nuxt.renderRoute("/"); let html = result.html; const meta = await axios.get("/someting-meta") html = html.replace(/<meta data-n-head="true" data-hid=“og:title".*?>/, `<meta title="og:title" content="${meta.title}">`) res.send(html) }); Ճ͠·ͨ͠
None
None
ΊͰͨ͠ɹΊͰͨ͠
メリット • ҠߦʹൺΕݕূίετ͕͍ܰ • طଘͷSPAͷॲཧΛݟ͞ͳͯ͘Α͍ • αʔόʔͰDOMͷܭࢉΛ͠ͳ͍ͰΑ͍ • expressΛىಈ͢Δඞཁ͋ΔͷͰɺ αʔόʔϦιʔεΛ৯Θͳ͍Θ͚Ͱͳ͍
デメリット • UniversalϞʔυͰ͍͍ͳΒ UniversalϞʔυͷ΄͏͕Α͍ • Expressͷ͕ࣝଟগඞཁ • Δ͜ͱ͕టष͍
デメリット2 • ϖʔδίϯϙʔωϯτͷϧʔςΟϯάͱ վ͟ΜॲཧͷϧʔςΟϯά͕Ұக͠ͳ͍ • NuxtͷࣗಈϧʔςΟϯάͷԸܙΛड͚ΒΕͳ͍ • ̍ϖʔδͷॲཧ͕2Օॴʹ͔ΕΔ • ରͷϖʔδ͕૿͑Δͱίʔυ͕ͨΒ͘ͳΔ
͍ͬͯ͏͔ UniversalϞʔυͰ͖ΔͳΒ ຊʹͦͷํ͕͍͍
ཁ݅ʹ߹Θͤͯ SPAϞʔυͰ։ൃΛਐΊ͍͍ͯͷ͔ ࠓҰߟ͑Α͏
SPAϞʔυ͡Ό OGPग़ͳ͍ͧͬʂ