diff --git a/src/components/RoadCard/RoadCardPage.tsx b/src/components/RoadCard/RoadCardPage.tsx
index 2f8675596..c9f9cd21b 100644
--- a/src/components/RoadCard/RoadCardPage.tsx
+++ b/src/components/RoadCard/RoadCardPage.tsx
@@ -34,7 +34,7 @@ export function RoadCardPage() {
}
const badgeUrl = new URL(
- `${import.meta.env.PUBLIC_API_URL}/v1-badge/${version}/${user?.id}`,
+ `${import.meta.env.PUBLIC_APP_URL}/card/${version}/${user?.id}`,
);
badgeUrl.searchParams.set('variant', variant);
@@ -146,7 +146,7 @@ export function RoadCardPage() {
className="flex cursor-pointer items-center justify-center rounded border border-gray-300 p-1.5 px-2 text-sm font-medium disabled:bg-blue-50"
onClick={() => copyText(badgeUrl.toString())}
>
-
+
{isCopied ? 'Copied!' : 'Copy Link'}
diff --git a/src/env.d.ts b/src/env.d.ts
index d52cd1cc6..7218154c2 100644
--- a/src/env.d.ts
+++ b/src/env.d.ts
@@ -4,6 +4,7 @@
interface ImportMetaEnv {
GITHUB_SHA: string;
PUBLIC_API_URL: string;
+ PUBLIC_APP_URL: string;
PUBLIC_AVATAR_BASE_URL: string;
PUBLIC_EDITOR_APP_URL: string;
}
diff --git a/src/lib/road-card.ts b/src/lib/road-card.ts
new file mode 100644
index 000000000..8aec82c1d
--- /dev/null
+++ b/src/lib/road-card.ts
@@ -0,0 +1,17 @@
+export async function getRoadCard(
+ version: 'tall' | 'wide',
+ userId: string,
+ variant: 'dark' | 'light',
+ roadmaps: string = '',
+) {
+ const url = new URL(
+ `${import.meta.env.PUBLIC_API_URL}/v1-badge/${version}/${userId}`,
+ );
+ url.searchParams.set('variant', variant);
+ if (roadmaps) {
+ url.searchParams.set('roadmaps', roadmaps);
+ }
+
+ const response = await fetch(url.toString());
+ return response.text();
+}
diff --git a/src/pages/card/[version]/[userId].ts b/src/pages/card/[version]/[userId].ts
new file mode 100644
index 000000000..a3a974b60
--- /dev/null
+++ b/src/pages/card/[version]/[userId].ts
@@ -0,0 +1,34 @@
+import type { APIRoute } from 'astro';
+import { getDefaultOpenGraphImageBuffer } from '../../../lib/open-graph';
+import { getRoadCard } from '../../../lib/road-card';
+
+export const prerender = false;
+
+type Params = {
+ version: 'tall' | 'wide';
+ userId: string;
+};
+
+export const GET: APIRoute = async (context) => {
+ const { userId, version } = context.params;
+
+ if (!userId || !version) {
+ const buffer = await getDefaultOpenGraphImageBuffer();
+ return new Response(buffer, {
+ headers: {
+ 'Content-Type': 'image/png',
+ },
+ });
+ }
+
+ const searchParams = new URLSearchParams(context.url.searchParams);
+ const variant = (searchParams.get('variant') as 'dark' | 'light') || 'dark';
+ const roadmaps = searchParams.get('roadmaps') || '';
+
+ const svg = await getRoadCard(version, userId, variant, roadmaps);
+ return new Response(svg, {
+ headers: {
+ 'Content-Type': 'image/svg+xml',
+ },
+ });
+};