diff --git a/apps/landing/package.json b/apps/landing/package.json index 41cbb88c4..214c5b0b9 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -20,6 +20,7 @@ "@svgr/webpack": "^6.5.1", "@tailwindcss/typography": "^0.5.9", "@vercel/analytics": "^0.1.8", + "@vercel/og": "^0.5.11", "autoprefixer": "^10.4.13", "class-variance-authority": "^0.6.0", "dayjs": "^1.11.7", @@ -31,7 +32,7 @@ "lodash": "^4.17.21", "nanoid": "^4.0.0", "next-i18next": "^13.0.3", - "next-seo": "^5.15.0", + "next-seo": "^6.1.0", "react-i18next": "^12.1.4", "react-use": "^17.4.0", "remark": "^14.0.3", @@ -39,7 +40,6 @@ "typescript": "^4.9.4" }, "devDependencies": { - "cross-env": "^7.0.3", "@next/bundle-analyzer": "^12.3.4", "@rallly/tsconfig": "*", "@types/accept-language-parser": "^1.5.3", @@ -53,6 +53,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.50.0", "cheerio": "^1.0.0-rc.12", + "cross-env": "^7.0.3", "eslint": "^7.26.0", "eslint-config-next": "^13.0.1", "eslint-config-turbo": "^0.0.9", diff --git a/apps/landing/public/static/fonts/inter-bold.ttf b/apps/landing/public/static/fonts/inter-bold.ttf new file mode 100644 index 000000000..8e82c70d1 Binary files /dev/null and b/apps/landing/public/static/fonts/inter-bold.ttf differ diff --git a/apps/landing/public/static/fonts/inter-regular.ttf b/apps/landing/public/static/fonts/inter-regular.ttf new file mode 100644 index 000000000..8d4eebf20 Binary files /dev/null and b/apps/landing/public/static/fonts/inter-regular.ttf differ diff --git a/apps/landing/src/pages/api/og-image.tsx b/apps/landing/src/pages/api/og-image.tsx new file mode 100644 index 000000000..9c3364133 --- /dev/null +++ b/apps/landing/src/pages/api/og-image.tsx @@ -0,0 +1,80 @@ +/* eslint-disable @next/next/no-img-element */ +import { ImageResponse } from "@vercel/og"; +import { NextRequest } from "next/server"; + +export const config = { + runtime: "edge", +}; + +const regularFont = fetch( + new URL("/public/static/fonts/inter-regular.ttf", import.meta.url), +).then((res) => res.arrayBuffer()); + +const boldFont = fetch( + new URL("/public/static/fonts/inter-bold.ttf", import.meta.url), +).then((res) => res.arrayBuffer()); + +export default async function handler(req: NextRequest) { + const [regularFontData, boldFontData] = await Promise.all([ + regularFont, + boldFont, + ]); + + const { searchParams } = req.nextUrl; + const title = searchParams.get("title"); + const excerpt = searchParams.get("excerpt"); + const type = searchParams.get("type"); + + return new ImageResponse( + ( +
+
+
+
+ Rallly +
+ {type} +
+
+
+

+ {title} +

+ {excerpt ? ( +

{excerpt}

+ ) : null} +
+
+ ), + { + width: 1200, + height: 630, + fonts: [ + { + name: "Inter", + data: regularFontData, + weight: 400, + }, + { + name: "Inter", + data: boldFontData, + weight: 700, + }, + ], + }, + ); +} diff --git a/apps/landing/src/pages/blog/[slug].tsx b/apps/landing/src/pages/blog/[slug].tsx index bf965eb1e..efb676638 100644 --- a/apps/landing/src/pages/blog/[slug].tsx +++ b/apps/landing/src/pages/blog/[slug].tsx @@ -1,10 +1,12 @@ import { ArrowLeftIcon } from "@rallly/icons"; +import { absoluteUrl } from "@rallly/utils"; import { GetStaticPropsContext } from "next"; import ErrorPage from "next/error"; import Head from "next/head"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; +import { NextSeo } from "next-seo"; import PostBody from "@/components/blog/post-body"; import PostHeader from "@/components/blog/post-header"; @@ -28,6 +30,29 @@ const Page: NextPageWithLayout = ({ post }) => { return (
+