diff --git a/app/api/og-image/route.tsx b/app/api/og-image/route.tsx new file mode 100644 index 0000000..1bd4cbe --- /dev/null +++ b/app/api/og-image/route.tsx @@ -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( + ( +
+
+ {title} +
+
+ ), + { + width: 1200, + height: 600, + fonts: [ + { + name: 'Inter', + data: fontData, + style: 'normal' + } + ] + } + ); +} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 4e773bd..5f51b5d 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -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 }) { diff --git a/app/services/page.tsx b/app/services/page.tsx index 3d90d4a..3edba97 100644 --- a/app/services/page.tsx +++ b/app/services/page.tsx @@ -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 = { diff --git a/assets/Inter.ttf b/assets/Inter.ttf new file mode 100644 index 0000000..053185e Binary files /dev/null and b/assets/Inter.ttf differ diff --git a/components/icons/CloudIcon.tsx b/components/icons/CloudIcon.tsx index 30f095d..be59d4a 100644 --- a/components/icons/CloudIcon.tsx +++ b/components/icons/CloudIcon.tsx @@ -4,7 +4,7 @@ export function CloudIcon(props: Props) { return ( - )