openvibers/openvibe.games Commits

Share the content-hashed Games card (#280)

OP OpenVibers committed 8 days ago · 379900c43e · 6 files, +33 −15

Every page now advertises openvibe-shared/social's 1200x630 games card (with its ?v content hash, dimensions and the Twitter mirror) instead of the retired og-image.png. The old image stays in public for links already shared.

Changes

ddiff --git a/apps/client/editor.html b/apps/client/editor.html
iindex 68e1afd..1436db9 100644
---- a/apps/client/editor.html
++++ b/apps/client/editor.html
@@@ -20,8 +20,11 @@
content="Collaborative map editor for Scraplandia on OpenVibe.Games."
/>
<meta property="og:url" content="https://openvibe.games/editor" />
-- <meta property="og:image" content="https://openvibe.games/og-image.png" />
++ <meta property="og:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
++ <meta property="og:image:width" content="1200" />
++ <meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
++ <meta name="twitter:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<!-- The OpenVibe Frame: the user's theme before first paint, then navbar + footer. -->
<script src="/shared/theme-loader.js"></script>
<script src="/shared/navbar.js" defer></script>
ddiff --git a/apps/client/index.html b/apps/client/index.html
iindex 908080d..b57f957 100644
---- a/apps/client/index.html
++++ b/apps/client/index.html
@@@ -26,7 +26,7 @@
content="Play Scraplandia, Salvage Rush or Vibe Heroes in your browser, no download: survival-building in Scrap City, timed scrap-collecting rounds, or an idle hero collector for your phone. One OpenVibe account across the whole network."
/>
<meta property="og:url" content="https://openvibe.games/" />
-- <meta property="og:image" content="https://openvibe.games/og-image.png" />
++ <meta property="og:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
@@@ -35,7 +35,7 @@
name="twitter:description"
content="Play Scraplandia, Salvage Rush and Vibe Heroes free in your browser, and see what's selling and on sale on Steam."
/>
-- <meta name="twitter:image" content="https://openvibe.games/og-image.png" />
++ <meta name="twitter:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<!-- JSON-LD (WebSite + the game as the site's primary type) is injected as this page is served,
built with openvibe-shared/seo so it stays in step with the other OpenVibe sites. -->
<style>
ddiff --git a/apps/client/leaderboard.html b/apps/client/leaderboard.html
iindex 97e1e44..5b265f4 100644
---- a/apps/client/leaderboard.html
++++ b/apps/client/leaderboard.html
@@@ -11,11 +11,11 @@
<meta property="og:title" content="Leaderboard · OpenVibe.Games" />
<meta property="og:description" content="OpenVibe.Games leaderboards: Salvage Rush best rounds and Scraplandia haul points, all time and this week. Scores come only from what the server played out." />
<meta property="og:url" content="https://openvibe.games/leaderboard.html" />
-- <meta property="og:image" content="https://openvibe.games/og-image.png" />
++ <meta property="og:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
-- <meta name="twitter:image" content="https://openvibe.games/og-image.png" />
++ <meta name="twitter:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<!-- The reader's theme, before the first paint: the page's own light rules follow it. -->
<script src="/shared/theme-loader.js"></script>
<style>
ddiff --git a/apps/client/play.html b/apps/client/play.html
iindex 2560b53..d7c1d1c 100644
---- a/apps/client/play.html
++++ b/apps/client/play.html
@@@ -20,7 +20,7 @@
content="Scrappy multiplayer survival-building in and around Scrap City. Physgun anything, weld it to anything else, haul your salvage home. No download."
/>
<meta property="og:url" content="https://play.openvibe.games/" />
-- <meta property="og:image" content="https://openvibe.games/og-image.png" />
++ <meta property="og:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
@@@ -29,7 +29,7 @@
name="twitter:description"
content="Multiplayer survival-building on the OpenVibe network. In your browser, no download."
/>
-- <meta name="twitter:image" content="https://openvibe.games/og-image.png" />
++ <meta name="twitter:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
@@@ -37,7 +37,7 @@
"@id": "https://play.openvibe.games/#game",
"name": "Scraplandia",
"url": "https://play.openvibe.games/",
-- "image": "https://openvibe.games/og-image.png",
++ "image": "https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47",
"description": "Scrappy multiplayer survival-building in and around Scrap City: physgun anything, weld it to anything else, chase supply drops in the wilds and haul your salvage home.",
"genre": ["Survival", "Sandbox", "Building"],
"playMode": "MultiPlayer",
ddiff --git a/apps/client/src/pages/pageMeta.test.ts b/apps/client/src/pages/pageMeta.test.ts
iindex 9d13079..7d0297e 100644
---- a/apps/client/src/pages/pageMeta.test.ts
++++ b/apps/client/src/pages/pageMeta.test.ts
@@@ -1,10 +1,11 @@
/**
* The pages outside the game client's router are still read by search engines and share cards:
-- * each names a one-line meta description of 120–160 characters, and the leaderboard (linked from
-- * the game and the portal) names its own canonical URL and the site's og:image, the card the home
-- * uses. The description is one line so a plain line-based crawler sees it too.
++ * each names a one-line meta description of 120–160 characters, and every page that had the old
++ * share image names the site's content-hashed card (openvibe-shared/social), with its size and the
++ * Twitter mirror. The description is one line so a plain line-based crawler sees it too.
*/
import { readFileSync } from 'node:fs'
++import { createRequire } from 'node:module'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
@@@ -12,6 +13,10 @@ const client = (path: string) => fileURLToPath(new URL(`../../${path}`, import.m
const html = (page: string) => readFileSync(client(page), 'utf8')
const description = (page: string) =>
/<meta name="description" content="([^"]*)" \/>/.exec(html(page))?.[1] ?? ''
++// The server already depends on the pinned openvibe-shared; its social helper is what names the card.
++const req = createRequire(new URL('../../../server/package.json', import.meta.url))
++const social = req('openvibe-shared/social') as { url(service: string): string | null }
++const CARD = `https://openvibe.games${social.url('games')}`
describe('page metadata', () => {
it.each(['play.html', 'worlds.html', 'leaderboard.html'])(
@@@ -25,9 +30,19 @@ describe('page metadata', () => {
},
)
-- it('leaderboard.html names its canonical URL and the site card', () => {
++ it('leaderboard.html names its canonical URL', () => {
const page = html('leaderboard.html')
expect(page).toContain('<link rel="canonical" href="https://openvibe.games/leaderboard.html" />')
-- expect(page).toContain('<meta property="og:image" content="https://openvibe.games/og-image.png" />')
})
++
++ it.each(['index.html', 'play.html', 'worlds.html', 'editor.html', 'leaderboard.html'])(
++ '%s shares the content-hashed site card',
++ (page) => {
++ const doc = html(page)
++ expect(doc).toContain(`<meta property="og:image" content="${CARD}" />`)
++ expect(doc).toContain('<meta property="og:image:width" content="1200" />')
++ expect(doc).toContain('<meta property="og:image:height" content="630" />')
++ expect(doc).toContain(`<meta name="twitter:image" content="${CARD}" />`)
++ },
++ )
})
ddiff --git a/apps/client/worlds.html b/apps/client/worlds.html
iindex 4f0ebab..859f6a2 100644
---- a/apps/client/worlds.html
++++ b/apps/client/worlds.html
@@@ -14,11 +14,11 @@
content="Build your own 3D world in the OpenVibe.Games map editor and publish it for anyone to join in the browser. Browse the worlds players made."
/>
<meta property="og:url" content="https://openvibe.games/worlds" />
-- <meta property="og:image" content="https://openvibe.games/og-image.png" />
++ <meta property="og:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
-- <meta name="twitter:image" content="https://openvibe.games/og-image.png" />
++ <meta name="twitter:image" content="https://openvibe.games/shared/social/games.jpg?v=a77ab4204f47" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<style>
/* The whole page follows the reader's theme (theme-loader.js sets --bg-primary, --text-primary, … on <html>); the dark