Test og images
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 2m42s

This commit is contained in:
r-freeman 2024-10-10 16:09:12 +01:00
parent ff5a2c910a
commit 829c6ba4be
5 changed files with 89 additions and 4 deletions

View File

@ -0,0 +1,63 @@
import {ImageResponse} from 'next/og'
export const runtime = 'edge'
const font = fetch(new URL('/assets/Inter.ttf', import.meta.url)).then(
(res) => res.arrayBuffer()
)
const gradients = [
'radial-gradient(at right top, rgb(221, 214, 254), rgb(239, 68, 68), rgb(251, 146, 60))',
'radial-gradient(at right bottom, rgb(255, 255, 255), rgb(244, 114, 182), rgb(240, 171, 252))',
'radial-gradient(at left bottom, rgb(254, 202, 202), rgb(8, 145, 178), rgb(236, 252, 203))',
'radial-gradient(at left top, rgb(124, 58, 237), rgb(220, 252, 231), rgb(31, 41, 55))',
'radial-gradient(at left bottom, rgb(214, 211, 209), rgb(190, 242, 100), rgb(190, 242, 100))'
]
export async function GET(request: Request) {
const fontData = await font
const {searchParams} = new URL(request.url)
const title = searchParams.get('title')
return new ImageResponse(
(
<div
style={{
fontSize: 64,
fontFamily: 'Inter',
background: 'black',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
lineHeight: '1',
padding: '0 128px'
}}
>
<div
style={{
backgroundImage: gradients[Math.floor(gradients.length * Math.random())],
backgroundClip: 'text',
// @ts-ignore
'-webkit-background-clip': 'text',
color: 'transparent',
}}>
{title}
</div>
</div>
),
{
width: 1200,
height: 600,
fonts: [
{
name: 'Inter',
data: fontData,
style: 'normal'
}
]
}
);
}

View File

@ -7,7 +7,11 @@ import '@/styles/tailwind.css'
export const metadata = {
title: 'Ryan Freeman - Full-stack software engineer from Dublin, Ireland.',
description: 'Full-stack software engineer who enjoys building cloud-native applications.'
description: 'Full-stack software engineer who enjoys building cloud-native applications.',
metadataBase: new URL('https://ryanfreeman.dev'),
alternates: {
canonical: '/'
}
}
export default function RootLayout({children}: { children: ReactNode }) {

View File

@ -10,10 +10,28 @@ import {EmailIcon} from '@/components/icons/EmailIcon'
import {RocketIcon} from '@/components/icons/RocketIcon'
import {ShoppingBagIcon} from '@/components/icons/ShoppingBagIcon'
export const metadata = {
const meta = {
title: 'Services - Ryan Freeman',
heading: 'I offer a wide range of digital services to elevate and transform your business',
description: 'Whether you need a WordPress website, React app, AWS support or odd coding jobs, I\'m here to help. ' +
'As an experienced software engineer, I produce high-quality software that will deliver immediate value for you and your customers.'
'As an experienced software engineer, I produce high-quality software that will deliver immediate value for you and your customers.',
}
export const metadata = {
...meta,
openGraph: {
title: meta.title,
description: meta.description,
images: [
{
url: `/api/og-image?title=${meta.heading}`,
width: 1200,
height: 600,
alt: meta.heading,
type: 'image/png'
}
]
}
}
type Services = {

BIN
assets/Inter.ttf Normal file

Binary file not shown.

View File

@ -4,7 +4,7 @@ export function CloudIcon(props: Props) {
return (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
{...props}>
<path stroke-linecap="round" stroke-linejoin="round"
<path strokeLinecap="round" strokeLinejoin="round"
d="M2.25 15a4.5 4.5 0 0 0 4.5 4.5H18a3.75 3.75 0 0 0 1.332-7.257 3 3 0 0 0-3.758-3.848 5.25 5.25 0 0 0-10.233 2.33A4.502 4.502 0 0 0 2.25 15Z"/>
</svg>
)