Skip to content
Merged
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
12 changes: 12 additions & 0 deletions src/app/day/2026/amsterdam/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SimpleOpengraphImage } from "../components/og-images/simple-opengraph-image"
export {
generateStaticParams,
contentType,
size,
} from "../components/og-images/simple-opengraph-image"

export default SimpleOpengraphImage.bind(null, {
pageTitle: "Amsterdam",
date: "Jun 9-10, 2026",
location: "Tolhuistuin, Amsterdam",
})
12 changes: 12 additions & 0 deletions src/app/day/2026/bengaluru/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SimpleOpengraphImage } from "../components/og-images/simple-opengraph-image"
export {
generateStaticParams,
contentType,
size,
} from "../components/og-images/simple-opengraph-image"

export default SimpleOpengraphImage.bind(null, {
pageTitle: "Bengaluru",
date: "Aug 19-20, 2026",
location: "Conrad Bengaluru, India",
})
2 changes: 1 addition & 1 deletion src/app/day/2026/components/graphql-day-logo-link.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { clsx } from "clsx"
import NextLink from "next/link"

function GraphQLDayLogo(props: React.SVGProps<SVGSVGElement>) {
export function GraphQLDayLogo(props: React.SVGProps<SVGSVGElement>) {
return (
<svg viewBox="0 0 100 100" fill="currentColor" {...props}>
<path d="M50 18.1409c4.8712 0 8.82-3.9488 8.82-8.82 0-4.87115-3.9488-8.82-8.82-8.82s-8.82 3.94885-8.82 8.82c0 4.8712 3.9488 8.82 8.82 8.82Zm35.2292 20.3396c4.8712 0 8.82-3.9488 8.82-8.82s-3.9488-8.82-8.82-8.82c-4.8711 0-8.82 3.9488-8.82 8.82s3.9489 8.82 8.82 8.82Zm0 40.6791c4.8712 0 8.82-3.9488 8.82-8.82s-3.9488-8.82-8.82-8.82c-4.8711 0-8.82 3.9488-8.82 8.82s3.9489 8.82 8.82 8.82ZM50 99.4991c4.8712 0 8.82-3.9488 8.82-8.82s-3.9488-8.82-8.82-8.82-8.82 3.9488-8.82 8.82 3.9488 8.82 8.82 8.82ZM14.7659 79.1596c4.8712 0 8.82-3.9488 8.82-8.82s-3.9488-8.82-8.82-8.82c-4.87115 0-8.82 3.9488-8.82 8.82s3.94885 8.82 8.82 8.82Zm0-40.6791c4.8712 0 8.82-3.9488 8.82-8.82s-3.9488-8.82-8.82-8.82c-4.87115 0-8.82 3.9488-8.82 8.82s3.94885 8.82 8.82 8.82ZM49.82 58.64c4.8712 0 8.82-3.9488 8.82-8.82S54.6912 41 49.82 41 41 44.9488 41 49.82s3.9488 8.82 8.82 8.82Z" />
Expand Down
179 changes: 179 additions & 0 deletions src/app/day/2026/components/og-images/day-opengraph-image-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { CalendarIcon } from "@/app/conf/_design-system/pixelarticons/calendar-icon"
import { PinIcon } from "@/app/conf/_design-system/pixelarticons/pin-icon"

import { GraphQLDayLogo } from "../graphql-day-logo-link"

export const OG_IMAGE_HEADER_HEIGHT = 154
export const RIGHT_COLUMN_WIDTH_PX = 476

/**
* We can't use CSS variables and Tailwind classes here because we're rendering an image.
* Mirrors src/app/colors.css.
*/
export const colors = {
neu0: "hsl(0 0% 100%)",
neu50: "hsl(75 57% 97%)",
neu100: "hsl(75 15% 95%)",
neu200: "hsl(77 14% 90%)",
neu300: "hsl(76 14% 85%)",
neu400: "hsl(77 14% 80%)",
neu500: "hsl(74 14% 70%)",
neu600: "hsl(76 15% 60%)",
neu700: "hsl(76 15% 40%)",
neu800: "hsl(77 14% 20%)",
neu900: "hsl(75 15% 5%)",
secLighter: "hsl(79 80% 90%)",
priBase: "hsl(319 100% 44.1%)",
}

export const fonts = {
sans: "'Host Grotesk', var(--font-sans)",
mono: "'Commit Mono', var(--font-mono)",
}

export function DayOpengraphImageHeader({
city,
date,
location,
}: {
city: string
date: string
location: string
}) {
return (
<header
style={{
display: "flex",
alignItems: "center",
borderBottom: `2px solid ${colors.neu600}`,
}}
>
<div
style={{
display: "flex",
flex: 1,
alignItems: "center",
gap: "1.5rem",
borderRight: `2px solid ${colors.neu600}`,
padding: "2.5rem",
paddingRight: "4rem",
height: OG_IMAGE_HEADER_HEIGHT,
}}
>
<div
style={{
display: "flex",
height: "74px",
alignItems: "center",
gap: "1rem",
fontFamily: fonts.mono,
fontSize: "40px",
lineHeight: "1",
textTransform: "uppercase",
color: colors.neu900,
}}
>
<GraphQLDayLogo
style={{
height: "3rem",
width: "3rem",
color: colors.priBase,
/* hack: satori aligns this SVG differently than browsers, it will look off center in /workroom,
but centered in the images */
marginTop: "-6px",
}}
/>
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
<span>GraphQL Day</span>
<span style={{ color: colors.priBase }}>2026</span>
</div>
</div>
</div>

<div
style={{
display: "flex",
height: "100%",
flexShrink: 0,
flexDirection: "column",
justifyContent: "center",
width: RIGHT_COLUMN_WIDTH_PX,
}}
>
<div
style={{
display: "flex",
alignItems: "center",
gap: "1.5rem",
borderBottom: `2px solid ${colors.neu600}`,
paddingLeft: "1.5rem",
paddingRight: "1.5rem",
paddingTop: "26px",
paddingBottom: "26px",
}}
>
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
<CalendarIcon
width="24"
height="24"
style={{
/* hack: different across satori and browsers */
transform: "translateY(-3px)",
color: colors.priBase,
}}
/>
<span
style={{
fontFamily: fonts.mono,
display: "flex",
fontSize: "1.25rem",
fontWeight: "normal",
textTransform: "uppercase",
lineHeight: "1.2",
color: colors.neu900,
}}
>
{date}
</span>
</div>
</div>

<div
style={{
display: "flex",
alignItems: "center",
gap: "1.5rem",
paddingLeft: "1.5rem",
paddingRight: "1.5rem",
paddingTop: "26px",
paddingBottom: "26px",
}}
>
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
<PinIcon
width="24"
height="24"
style={{
/* hack: different across satori and browsers */
transform: "translateY(-2px)",
color: colors.priBase,
}}
/>
<span
style={{
fontFamily: fonts.mono,
fontSize: "1.25rem",
fontWeight: "normal",
textTransform: "uppercase",
lineHeight: "1.2",
color: colors.neu900,
}}
>
{location}
</span>
</div>
</div>
</div>
</header>
)
}
104 changes: 104 additions & 0 deletions src/app/day/2026/components/og-images/generic-opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { readFileSync } from "node:fs"
import { resolve } from "node:path"

import {
colors,
DayOpengraphImageHeader,
fonts,
OG_IMAGE_HEADER_HEIGHT,
} from "./day-opengraph-image-header"

const graphqlLogoStripesDataUri = `data:image/png;base64,${readFileSync(
resolve(
process.cwd(),
"src/app/day/2026/components/og-images/graphql-logo-stripes.png",
),
).toString("base64")}`

export interface GenericDayOpengraphImageProps
extends React.HTMLAttributes<HTMLElement> {
pageTitle: string
date: string
location: string
}

export function GenericDayOpengraphImage({
pageTitle,
date,
location,
...rest
}: GenericDayOpengraphImageProps) {
const height = 630

return (
<article
style={{
display: "flex",
height,
width: "1200px",
flexDirection: "column",
overflow: "hidden",
borderWidth: "2px",
borderColor: colors.neu600,
backgroundColor: colors.neu100,
fontFamily: fonts.sans,
}}
{...rest}
>
<DayOpengraphImageHeader
city={pageTitle}
date={date}
location={location}
/>

<div
style={{
display: "flex",
flex: 1,
flexDirection: "column",
justifyContent: "flex-start",
padding: "2.5rem",
position: "relative",
}}
>
<h1
style={{
display: "flex",
flexDirection: "column",
margin: 0,
fontFamily: fonts.sans,
lineHeight: "1.25",
fontWeight: "bold",
fontSize: "72px",
}}
>
<span style={{ color: colors.neu900 }}>GraphQL Day</span>
<span style={{ color: colors.priBase }}>at FOST {pageTitle}</span>
</h1>
<div
style={{
display: "flex",
alignSelf: "flex-start",
marginTop: "2.5rem",
alignItems: "center",
justifyContent: "center",
backgroundColor: colors.neu900,
color: colors.neu0,
fontFamily: fonts.sans,
fontSize: "1.75rem",
height: "4.5rem",
padding: "0 2.5rem",
}}
>
Register now
</div>
<img
src={graphqlLogoStripesDataUri}
style={{ position: "absolute", right: 0, bottom: -5 }}
height={height - OG_IMAGE_HEADER_HEIGHT}
width={673}
/>
</div>
</article>
)
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions src/app/day/2026/components/og-images/simple-opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ImageResponse } from "next/og"

import { loadFontsForOG } from "@/app/fonts/og/load-fonts-for-og"

import { GenericDayOpengraphImage } from "./generic-opengraph-image"

export const contentType = "image/png"
export const size = {
width: 1200,
height: 630,
}

export function generateStaticParams() {
return [{}]
}

export async function SimpleOpengraphImage({
pageTitle,
date,
location,
}: {
pageTitle: string
date: string
location: string
}) {
const fonts = loadFontsForOG()

return new ImageResponse(
(
<GenericDayOpengraphImage
pageTitle={pageTitle}
date={date}
location={location}
/>
),
{
...size,
fonts: await fonts,
},
)
}
12 changes: 12 additions & 0 deletions src/app/day/2026/london/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SimpleOpengraphImage } from "../components/og-images/simple-opengraph-image"
export {
generateStaticParams,
contentType,
size,
} from "../components/og-images/simple-opengraph-image"

export default SimpleOpengraphImage.bind(null, {
pageTitle: "London",
date: "Sep 30-Oct 1, 2026",
location: "Convene Sancroft, London",
})
12 changes: 12 additions & 0 deletions src/app/day/2026/melbourne/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SimpleOpengraphImage } from "../components/og-images/simple-opengraph-image"
export {
generateStaticParams,
contentType,
size,
} from "../components/og-images/simple-opengraph-image"

export default SimpleOpengraphImage.bind(null, {
pageTitle: "Melbourne",
date: "Oct 28-29, 2026",
location: "Melbourne, Australia",
})
Loading
Loading