Description
Sharing a public invoice status link on social media or in a messaging app generates a blank preview because the page lacks Open Graph meta tags. Proper OG and Twitter card metadata generated server-side from the invoice record must be added to the public invoice route.
Technical Context
src/app/invoice/[id]/public/page.tsx (or the existing public page route) uses Next.js App Router's generateMetadata async export to fetch the invoice and return { openGraph: { title, description, images } }. The OG image is a dynamic Next.js Image Response from src/app/og/route.tsx (new) using the @vercel/og package, rendering the invoice title, total, and status in a branded card layout. generateMetadata sets a robots: 'noindex' directive for draft invoices.
Acceptance Criteria
Description
Sharing a public invoice status link on social media or in a messaging app generates a blank preview because the page lacks Open Graph meta tags. Proper OG and Twitter card metadata generated server-side from the invoice record must be added to the public invoice route.
Technical Context
src/app/invoice/[id]/public/page.tsx(or the existing public page route) uses Next.js App Router'sgenerateMetadataasync export to fetch the invoice and return{ openGraph: { title, description, images } }. The OG image is a dynamic Next.js Image Response fromsrc/app/og/route.tsx(new) using the@vercel/ogpackage, rendering the invoice title, total, and status in a branded card layout.generateMetadatasets arobots: 'noindex'directive for draft invoices.Acceptance Criteria
<title>tag reads "Invoice #<id> — StellarSplit" or similar<meta name="robots" content="noindex">to prevent indexinggenerateMetadatadoes not block render; it runs in parallel with the page data fetch