feat(web): implement public profile page with Open Graph meta tags for /u/:username#345
Open
samarthsugandhi wants to merge 2 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a public, unauthenticated “shareable profile” surface by introducing a backend endpoint, shared response types, and a simplified web profile page with Open Graph/SEO meta tags.
Changes:
- Added shared
PublicCardResponse/PublicCardLinktypes for the public card API. - Added backend route
GET /public/cards/:usernameto serve safe, public profile data. - Updated
/u/[username]page to render from the public API shape and emit OG/Twitter/canonical meta tags.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
| packages/shared/src/types.ts | Introduces shared TS interfaces for the public card API response. |
| apps/web/src/routes/u/[username]/+page.svelte | Reworks the public profile page UI and adds OG/Twitter/canonical meta tags. |
| apps/backend/src/routes/publicCards.ts | Adds an unauthenticated public endpoint to fetch a user’s default card links. |
| apps/backend/src/app.ts | Registers the new publicCardRoutes route module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const error = data.error; | ||
| export let data: PageData; | ||
|
|
||
| const card: PublicCardResponse = data.card; |
| {:else} | ||
| <title>User Not Found | DevCard</title> | ||
| {/if} | ||
| <title>{card.displayName ?? card.username} | DevCard</title> |
| <main class="profile-page"> | ||
| <div class="card"> | ||
| <!-- Avatar --> | ||
| {#if card.avatarUrl} |
| {/if} | ||
|
|
||
| <!-- Name + username --> | ||
| <h1 class="display-name">{card.displayName ?? card.username}</h1> |
| {/if} | ||
|
|
||
| <!-- Platform links --> | ||
| {#if card.links.length > 0} |
| } | ||
|
|
||
| // Build the page URL for the canonical + og:url tag | ||
| const pageUrl = `https://dev-card-web.vercel.app/u/${card.username}`; |
| <meta property="og:url" content={pageUrl} /> | ||
| <meta | ||
| property="og:image" | ||
| content={card.avatarUrl ?? "https://dev-card-web.vercel.app/og-image.jpg"} |
| <meta name="twitter:description" content={ogDescription} /> | ||
| <meta | ||
| name="twitter:image" | ||
| content={card.avatarUrl ?? "https://dev-card-web.vercel.app/og-image.jpg"} |
| /> | ||
|
|
||
| <!-- Canonical URL --> | ||
| <link rel="canonical" href={pageUrl} /> |
Comment on lines
+27
to
+55
| schema: { | ||
| params: { | ||
| type: "object", | ||
| required: ["username"], | ||
| properties: { | ||
| username: { type: "string" }, | ||
| }, | ||
| }, | ||
| response: { | ||
| 200: { | ||
| type: "object", | ||
| properties: { | ||
| username: { type: "string" }, | ||
| displayName: { type: ["string", "null"] }, | ||
| bio: { type: ["string", "null"] }, | ||
| avatarUrl: { type: ["string", "null"] }, | ||
| links: { | ||
| type: "array", | ||
| items: { | ||
| type: "object", | ||
| properties: { | ||
| platform: { type: "string" }, | ||
| url: { type: "string" }, | ||
| label: { type: ["string", "null"] }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, |
Author
|
@ShantKhatri Hi! Could you please review this PR when you get a chance? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the public-facing profile page at
/u/:usernamethat renders a user's DevCard with all platform links, and injects dynamic Open Graph meta tags so the URL generates a rich link preview when shared on Twitter/X, LinkedIn, WhatsApp, or Telegram.Closes #239
Changes Made
apps/web/src/routes/u/[username]/+page.svelte(modified)data.profileanddata.errorfrom the existing+page.server.tsload function (no changes needed there)apps/web/src/routes/u/[username]/+page.svelte— Open Graph tags addedog:title— user's display name or usernameog:description— user's bio, or a generated fallbackog:image— user's avatar URL, or the site default OG imageog:url— canonical URL for the profiletwitter:card— set tosummaryfor Twitter/X previews<link rel="canonical">— added for SEOpackages/shared/src/types.ts(modified)PublicProfileandPublicCardLinkinterfaces matching the shape returned by the backendHow to Test
pnpm devfrom the repo roothttp://localhost:5173/u/<any-seeded-username>http://localhost:5173/u/nonexistent— you should see the "Profile not found" error page<meta property="og:title">and other OG tags are present in the<head>Checklist
rel="noopener noreferrer"pnpm lintpasses with no errors+page.server.tsleft unchanged