mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 04:37:11 +01:00
refactor(route): streamline Open Graph meta tag generation for bots
- Introduced a new metaTag function to simplify the creation of meta tags for Open Graph and Twitter. - Replaced regex-based bot detection with the isbot library for improved accuracy. - Enhanced the GET route to conditionally render meta tags based on available link metadata, improving SEO and social media sharing capabilities.
This commit is contained in:
parent
39d4c6fc93
commit
dd2de94548
1 changed files with 30 additions and 36 deletions
|
|
@ -1,5 +1,6 @@
|
|||
export const dynamic = 'force-dynamic';
|
||||
|
||||
import { isbot } from 'isbot';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { POST } from '@/app/api/send/route';
|
||||
import type { Link } from '@/generated/prisma/client';
|
||||
|
|
@ -16,6 +17,14 @@ function escapeHtml(str: string): string {
|
|||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function metaTag(property: string, content: string | undefined, isName = false): string {
|
||||
if (!content) return '';
|
||||
const escaped = escapeHtml(content);
|
||||
return isName
|
||||
? `<meta name="${property}" content="${escaped}">`
|
||||
: `<meta property="${property}" content="${escaped}">`;
|
||||
}
|
||||
|
||||
export async function GET(request: Request, { params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params;
|
||||
|
||||
|
|
@ -50,27 +59,12 @@ export async function GET(request: Request, { params }: { params: Promise<{ slug
|
|||
}
|
||||
|
||||
const userAgent = request.headers.get('user-agent') || '';
|
||||
const isBot =
|
||||
/facebookexternalhit|twitterbot|linkedinbot|whatsapp|slackbot|discordbot|telegrambot|applebot|bingbot|googlebot/i.test(
|
||||
userAgent,
|
||||
);
|
||||
|
||||
if (isBot) {
|
||||
const ogTitle = escapeHtml(link.ogTitle || link.name);
|
||||
const ogDescription = escapeHtml(link.ogDescription || '');
|
||||
const ogImageUrl = escapeHtml(link.ogImageUrl || '');
|
||||
const ogDescriptionTag = ogDescription
|
||||
? `<meta property="og:description" content="${ogDescription}">`
|
||||
: '';
|
||||
const ogImageTag = ogImageUrl ? `<meta property="og:image" content="${ogImageUrl}">` : '';
|
||||
if (isbot(userAgent)) {
|
||||
const ogTitle = link.ogTitle || link.name;
|
||||
const ogDescription = link.ogDescription || undefined;
|
||||
const ogImageUrl = link.ogImageUrl || undefined;
|
||||
const twitterCard = ogImageUrl ? 'summary_large_image' : 'summary';
|
||||
const metaDescriptionTag = ogDescription
|
||||
? `<meta name="description" content="${ogDescription}">`
|
||||
: '';
|
||||
const twitterDescriptionTag = ogDescription
|
||||
? `<meta name="twitter:description" content="${ogDescription}">`
|
||||
: '';
|
||||
const twitterImageTag = ogImageUrl ? `<meta name="twitter:image" content="${ogImageUrl}">` : '';
|
||||
|
||||
return new Response(
|
||||
`
|
||||
|
|
@ -78,29 +72,29 @@ export async function GET(request: Request, { params }: { params: Promise<{ slug
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>${ogTitle}</title>
|
||||
|
||||
<meta name="title" content="${ogTitle}">
|
||||
${metaDescriptionTag}
|
||||
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:site_name" content="Umami">
|
||||
<meta property="og:title" content="${ogTitle}">
|
||||
<meta property="og:url" content="${request.url}">
|
||||
${ogDescriptionTag}
|
||||
${ogImageTag}
|
||||
|
||||
<title>${escapeHtml(ogTitle)}</title>
|
||||
${metaTag('title', ogTitle, true)}
|
||||
${metaTag('description', ogDescription, true)}
|
||||
${metaTag('og:type', 'website')}
|
||||
${metaTag('og:site_name', 'Umami')}
|
||||
${metaTag('og:title', ogTitle)}
|
||||
${metaTag('og:url', request.url)}
|
||||
${metaTag('og:description', ogDescription)}
|
||||
${metaTag('og:image', ogImageUrl)}
|
||||
<meta name="twitter:card" content="${twitterCard}">
|
||||
<meta name="twitter:title" content="${ogTitle}">
|
||||
${twitterDescriptionTag}
|
||||
${twitterImageTag}
|
||||
${metaTag('twitter:title', ogTitle, true)}
|
||||
${metaTag('twitter:description', ogDescription, true)}
|
||||
${metaTag('twitter:image', ogImageUrl, true)}
|
||||
</head>
|
||||
<body></body>
|
||||
<body>
|
||||
<p>Redirecting to ${escapeHtml(link.url)}...</p>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
`,
|
||||
{
|
||||
headers: {
|
||||
'content-type': 'text/html',
|
||||
'cache-control': 's-maxage=300, stale-while-revalidate',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue