Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions components/PageMeta.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import Head from 'next/head';

const site = {
title: 'React Native Directory',
description: 'An interactive directory to find packages for your React Native apps.',
};

const BASE_OG_URL = 'https://og.expo.dev/?theme=rnd';
import { BASE_META } from '~/util/Constants';

type PageMetaProps = {
title?: string;
Expand All @@ -18,15 +13,15 @@ export default function PageMeta({
title,
searchQuery,
path,
description = site.description,
description = BASE_META.description,
}: PageMetaProps) {
const pageTitle = `${title ? title + ' • ' : ''}${site.title}`;
const pageTitle = `${title ? title + ' • ' : ''}${BASE_META.title}`;
const parsedSearchQuery = Array.isArray(searchQuery) ? searchQuery[0] : searchQuery;
const finalDescription = parsedSearchQuery
? `Search results for keyword: '${parsedSearchQuery}'`
: description;

const socialImage = `${BASE_OG_URL}&title=${encodeURIComponent(pageTitle)}&description=${encodeURIComponent(finalDescription)}`;
const socialImage = `https://${window.location.host}/api/proxy/og?title=${encodeURIComponent(pageTitle)}&description=${encodeURIComponent(finalDescription)}`;

return (
<Head>
Expand Down
39 changes: 39 additions & 0 deletions pages/api/proxy/og.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { type NextApiRequest, type NextApiResponse } from 'next';

import { BASE_META, NEXT_1H_CACHE_HEADER } from '~/util/Constants';
import { parseQueryParams } from '~/util/parseQueryParams';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { title, description } = parseQueryParams(req.query);

const ogTitle = title ? title.toString().trim() : BASE_META.title;
const ogDescription = description ? description.toString().trim() : BASE_META.description;

res.setHeader('Cache-Control', 'public, s-maxage=600, stale-while-revalidate=300');

const result = await fetch(
`https://og.expo.dev/?theme=rnd&title=${encodeURIComponent(ogTitle)}&description=${encodeURIComponent(ogDescription)}`,
NEXT_1H_CACHE_HEADER
);

if (!result.ok) {
res.setHeader('Content-Type', 'application/json');
res.statusCode = 502;
return res.json({ error: `Failed to fetch OG image.` });
}

const upstreamContentType = result.headers.get('content-type') ?? 'image/png';
const upstreamContentLength = result.headers.get('content-length');

if (upstreamContentLength) {
res.setHeader('Content-Length', upstreamContentLength);
}

res.setHeader('Content-Type', upstreamContentType);
res.statusCode = 200;

const arrayBuffer = await result.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);

return res.send(buffer);
}
5 changes: 5 additions & 0 deletions util/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { TimeRange } from '~/util/datetime';

export const BASE_META = {
title: 'React Native Directory',
description: 'An interactive directory to find packages for your React Native apps.',
};

export const NUM_PER_PAGE = 30;

export const EMPTY_PACKAGE_DATA = {
Expand Down