feat: add shareable meme permalinks
This commit is contained in:
+38
-20
@@ -13,36 +13,54 @@ export function publicBaseUrl(req) {
|
||||
return cleanBase(`${proto}://${host || 'localhost:8080'}`);
|
||||
}
|
||||
|
||||
export function renderIndex({ template, baseUrl, nonce, approvedCount }) {
|
||||
const canonical = `${baseUrl}/`;
|
||||
const image = `${baseUrl}/assets/yoonect-logo.png`;
|
||||
const jsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@graph': [
|
||||
{
|
||||
'@type': 'WebSite',
|
||||
'@id': `${canonical}#website`,
|
||||
name: SITE_NAME,
|
||||
export function renderIndex({ template, baseUrl, nonce, approvedCount, meme = null }) {
|
||||
const home = `${baseUrl}/`;
|
||||
const canonical = meme ? `${baseUrl}/meme/${meme.id}` : home;
|
||||
const image = meme ? `${baseUrl}/media/${meme.id}` : `${baseUrl}/assets/yoonect-logo.png`;
|
||||
const title = meme ? `Meme ${shortId(meme.id)} | ${SITE_NAME}` : SITE_NAME;
|
||||
const description = meme
|
||||
? `View and share meme ${shortId(meme.id)} on ${SITE_NAME}.`
|
||||
: SITE_DESCRIPTION;
|
||||
const pageMetadata = meme
|
||||
? {
|
||||
'@type': 'ImageObject',
|
||||
'@id': `${canonical}#meme`,
|
||||
name: `Meme ${shortId(meme.id)}`,
|
||||
contentUrl: image,
|
||||
url: canonical,
|
||||
description: SITE_DESCRIPTION,
|
||||
inLanguage: 'en'
|
||||
},
|
||||
{
|
||||
uploadDate: meme.createdAt,
|
||||
width: meme.width,
|
||||
height: meme.height,
|
||||
isPartOf: { '@id': `${home}#website` }
|
||||
}
|
||||
: {
|
||||
'@type': 'CollectionPage',
|
||||
'@id': `${canonical}#collection`,
|
||||
name: SITE_NAME,
|
||||
url: canonical,
|
||||
description: SITE_DESCRIPTION,
|
||||
isPartOf: { '@id': `${canonical}#website` },
|
||||
isPartOf: { '@id': `${home}#website` },
|
||||
about: ['memes', 'internet culture', 'image gallery', 'community moderation'],
|
||||
numberOfItems: approvedCount
|
||||
};
|
||||
const jsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@graph': [
|
||||
{
|
||||
'@type': 'WebSite',
|
||||
'@id': `${home}#website`,
|
||||
name: SITE_NAME,
|
||||
url: home,
|
||||
description: SITE_DESCRIPTION,
|
||||
inLanguage: 'en'
|
||||
},
|
||||
pageMetadata,
|
||||
{
|
||||
'@type': 'SoftwareApplication',
|
||||
name: SITE_NAME,
|
||||
applicationCategory: 'MultimediaApplication',
|
||||
operatingSystem: 'Web',
|
||||
url: canonical,
|
||||
url: home,
|
||||
codeRepository: REPO_URL,
|
||||
offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' }
|
||||
}
|
||||
@@ -50,8 +68,8 @@ export function renderIndex({ template, baseUrl, nonce, approvedCount }) {
|
||||
};
|
||||
|
||||
return template
|
||||
.replaceAll('__SEO_TITLE__', escapeHtml(SITE_NAME))
|
||||
.replaceAll('__SEO_DESCRIPTION__', escapeHtml(SITE_DESCRIPTION))
|
||||
.replaceAll('__SEO_TITLE__', escapeHtml(title))
|
||||
.replaceAll('__SEO_DESCRIPTION__', escapeHtml(description))
|
||||
.replaceAll('__SEO_CANONICAL__', canonical)
|
||||
.replaceAll('__SEO_IMAGE__', image)
|
||||
.replaceAll('__SEO_JSON_LD__', escapeJsonScript(JSON.stringify(jsonLd)))
|
||||
@@ -125,7 +143,7 @@ export function feedJson(baseUrl, memes) {
|
||||
description: SITE_DESCRIPTION,
|
||||
items: memes.slice(0, 50).map((meme) => ({
|
||||
id: meme.id,
|
||||
url: `${baseUrl}/media/${meme.id}`,
|
||||
url: `${baseUrl}/meme/${meme.id}`,
|
||||
image: `${baseUrl}/media/${meme.id}`,
|
||||
title: `Meme ${shortId(meme.id)}`,
|
||||
content_text: `Approved meme with MEME_CONSENSUS_SCORE ${meme.moderationScore}/100.`,
|
||||
@@ -145,7 +163,7 @@ export function sitemapXml(baseUrl, memes) {
|
||||
].join('\n'),
|
||||
...memes.slice(0, 1000).map((meme) => [
|
||||
' <url>',
|
||||
` <loc>${xmlEscape(`${baseUrl}/media/${meme.id}`)}</loc>`,
|
||||
` <loc>${xmlEscape(`${baseUrl}/meme/${meme.id}`)}</loc>`,
|
||||
` <lastmod>${xmlEscape(meme.createdAt)}</lastmod>`,
|
||||
' </url>'
|
||||
].join('\n'))
|
||||
|
||||
Reference in New Issue
Block a user