@@ -5,6 +5,8 @@ import { fetchArtists, fetchShowByUUID } from '@/app/queries';
55import { ImageResponse } from 'next/og' ;
66import { NextRequest } from 'next/server' ;
77import { notFound } from 'next/navigation' ;
8+ import { createZodRoute } from 'next-zod-route' ;
9+ import { z } from 'zod' ;
810
911export const runtime = 'edge' ;
1012
@@ -75,9 +77,9 @@ const getArtistGradient = (uuid: string) => {
7577 return gradientString ;
7678} ;
7779
78- const generatePixelatedSVG = ( opacity = 0.4 ) => {
79- // Create a pixelated pattern with large squares
80- const squareSize = 45 ; // Size of each pixel square
80+ // Create a pixelated pattern with large squares
81+ const generatePixelatedSVG = ( opacity = 0.4 , size : number ) => {
82+ const squareSize = ( size / 1024 ) * 45 ; // Size of each pixel square
8183 const gridSize = 10 ; // Number of squares in each row/column
8284 const borderWidth = 1 ; // Reduced width of the border between pixels
8385 const borderColor = 'rgba(0, 0, 0, 0.1)' ; // More transparent black for subtler borders
@@ -108,16 +110,19 @@ const generatePixelatedSVG = (opacity = 0.4) => {
108110 return `url("data:image/svg+xml;base64,${ Buffer . from ( svg ) . toString ( 'base64' ) } ")` ;
109111} ;
110112
111- export async function GET ( request : NextRequest ) {
112- try {
113- const { searchParams } = new URL ( request . url ) ;
113+ const querySchema = z . object ( {
114+ showUuid : z . string ( ) . uuid ( ) ,
115+ size : z . coerce . number ( ) . gte ( 256 ) . lte ( 1024 ) . default ( 1024 ) ,
116+ } ) ;
114117
115- const showUuid = searchParams . get ( 'showUuid' ) ;
116- if ( ! showUuid ) return notFound ( ) ;
118+ export const GET = createZodRoute ( )
119+ . query ( querySchema )
120+ . handler ( async ( request , context ) => {
121+ if ( ! context . query . showUuid ) return notFound ( ) ;
117122
118123 const [ artists , show , fontReg , fontBold , fontMegaBold ] = await Promise . all ( [
119124 fetchArtists ( ) ,
120- fetchShowByUUID ( showUuid ) ,
125+ fetchShowByUUID ( context . query . showUuid ) ,
121126 fetch (
122127 new URL ( 'https://cdn.jsdelivr.net/fontsource/fonts/roboto@latest/latin-400-normal.ttf' ) ,
123128 { next : { revalidate : 60 * 60 * 24 * 30 } } // Cache for 30 days
@@ -141,7 +146,8 @@ export async function GET(request: NextRequest) {
141146 // Generate dynamic background color and pattern based on artist UUID
142147 const bgGradient = getArtistGradient ( show . artist_uuid || '' ) ;
143148 // Generate pixelated background pattern
144- const pixelatedSVG = generatePixelatedSVG ( 0.8 ) ;
149+ const size = context . query . size ;
150+ const pixelatedSVG = generatePixelatedSVG ( 0.8 , size ) ;
145151
146152 return new ImageResponse (
147153 (
@@ -153,23 +159,49 @@ export async function GET(request: NextRequest) {
153159 } }
154160 >
155161 < div tw = "flex w-full max-w-[800px] flex-col items-center justify-center rounded-2xl bg-black/25 p-12 relative" >
156- < div tw = "mb-2 text-center text-7xl font-extrabold tracking-tight" > { artistName } </ div >
157- < div tw = "mb-2 text-center text-6xl font-bold" > { show . display_date } </ div >
162+ < div
163+ tw = "mb-2 text-center font-extrabold tracking-tight"
164+ style = { {
165+ fontSize : ( size / 1024 ) * 72 ,
166+ } }
167+ >
168+ { artistName }
169+ </ div >
170+ < div
171+ tw = "mb-2 text-center font-bold"
172+ style = { {
173+ fontSize : ( size / 1024 ) * 60 ,
174+ } }
175+ >
176+ { show . display_date }
177+ </ div >
158178 < div tw = "flex items-center justify-center" style = { { gap : 8 } } >
159179 { show . venue ?. name && (
160- < div tw = "rounded-xl bg-white/20 px-6 py-3 text-4xl flex text-center" >
180+ < div
181+ tw = "rounded-xl bg-white/20 px-6 py-3 flex text-center"
182+ style = { {
183+ fontSize : ( size / 1024 ) * 36 ,
184+ } }
185+ >
161186 { show . venue ?. name } { show . venue ?. location ? `• ${ show . venue . location } ` : '' }
162187 </ div >
163188 ) }
164189 </ div >
165190 </ div >
166191
167- < div tw = "absolute bottom-6 right-6 text-4xl font-bold" > Relisten.net</ div >
192+ < div
193+ tw = "absolute bottom-6 right-6 font-bold"
194+ style = { {
195+ fontSize : ( size / 1024 ) * 36 ,
196+ } }
197+ >
198+ Relisten.net
199+ </ div >
168200 </ div >
169201 ) ,
170202 {
171- width : 1024 ,
172- height : 1024 ,
203+ width : size ,
204+ height : size ,
173205 fonts : [
174206 {
175207 name : 'Roboto' ,
@@ -192,8 +224,4 @@ export async function GET(request: NextRequest) {
192224 ] ,
193225 }
194226 ) ;
195- } catch ( error ) {
196- console . error ( 'Error generating album art:' , error ) ;
197- return new Response ( 'Error generating album art' , { status : 500 } ) ;
198- }
199- }
227+ } ) ;
0 commit comments