From eff96e5a374707908d24efcfc85e3003af4f918c Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Mon, 20 Jan 2025 03:51:21 -0800 Subject: [PATCH] More work on image embeds (#423) * Writes redirect for preview images so we're not embedding the API URL in user-facing pages * Adds the NextJs API page that actually serves the image * Use a more straightforward URL construction method * Add the og:image:width and og:image:height --- components/party/PartyHead/index.tsx | 6 ++++- next.config.js | 4 ++++ pages/api/preview/[shortcode].ts | 33 ++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 pages/api/preview/[shortcode].ts diff --git a/components/party/PartyHead/index.tsx b/components/party/PartyHead/index.tsx index a471c5bb..d4df3b69 100644 --- a/components/party/PartyHead/index.tsx +++ b/components/party/PartyHead/index.tsx @@ -19,7 +19,9 @@ const PartyHead = ({ party, meta }: Props) => { const router = useRouter() const locale = router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' - const previewUrl = api.previewUrl(party.id) + const previewUrl = `${ + process.env.NEXT_PUBLIC_SITE_URL || 'https://granblue.team' + }/preview/${party.shortcode}` return ( @@ -55,6 +57,8 @@ const PartyHead = ({ party, meta }: Props) => { /> + + {/* Twitter */} diff --git a/next.config.js b/next.config.js index 08b44b2b..3e1f26f4 100644 --- a/next.config.js +++ b/next.config.js @@ -35,6 +35,10 @@ module.exports = { source: '/roadmap', destination: '/about', }, + { + source: '/p/:shortcode/preview', + destination: '/api/preview/:shortcode', + }, { source: '/p/:shortcode/characters', destination: '/p/:shortcode', diff --git a/pages/api/preview/[shortcode].ts b/pages/api/preview/[shortcode].ts new file mode 100644 index 00000000..12056dc1 --- /dev/null +++ b/pages/api/preview/[shortcode].ts @@ -0,0 +1,33 @@ +import type { NextApiRequest, NextApiResponse } from 'next' +import axios from 'axios' + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + const { shortcode } = req.query + + if (!shortcode || Array.isArray(shortcode)) { + return res.status(400).json({ error: 'Invalid shortcode' }) + } + + try { + const response = await axios({ + method: 'GET', + url: `${process.env.API_URL}/api/v1/parties/${shortcode}/preview`, + responseType: 'arraybuffer', + headers: { + Accept: 'image/png', + }, + }) + + // Set correct content type and caching headers + res.setHeader('Content-Type', 'image/png') + res.setHeader('Cache-Control', 'public, max-age=31536000, immutable') + + return res.send(response.data) + } catch (error) { + console.error('Error fetching preview:', error) + return res.status(500).json({ error: 'Failed to fetch preview' }) + } +}