Skip to content

Instantly share code, notes, and snippets.

@ja3nyc
Last active July 31, 2025 11:56
Show Gist options
  • Select an option

  • Save ja3nyc/0f851f06920850292a7bb27b698eec8f to your computer and use it in GitHub Desktop.

Select an option

Save ja3nyc/0f851f06920850292a7bb27b698eec8f to your computer and use it in GitHub Desktop.
import { Resvg } from '@resvg/resvg-js';
import satori from 'satori';
import { opensansBold, opensansRegular } from './fonts';
export async function generateNoteOgImage({
title,
subtitle,
width = 1200,
height = 630,
}: {
title: string;
subtitle?: string;
width?: number;
height?: number;
}): Promise<Buffer> {
const svg = await satori(
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
padding: '60px',
backgroundColor: '#ffffff',
backgroundImage: `url(${process.env.NEXT_PUBLIC_NEW_SITE_URL}/og/og-bg-note.png)`,
backgroundSize: 'cover',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '24px',
maxWidth: '85%',
}}
>
<div
style={{
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: 2, // Changed from 3 to 2
overflow: 'hidden',
fontSize: title.length > 40 ? 64 : 80,
fontWeight: 700,
fontFamily: 'system-ui, sans-serif',
letterSpacing: '-0.03em',
color: '#000000',
lineHeight: 1.1,
wordBreak: 'break-word',
textOverflow: 'ellipsis', // Add ellipsis for overflow
}}
>
{title}
</div>
<div
style={{
display: 'flex',
fontSize: 36,
fontWeight: 500,
fontFamily: 'system-ui, sans-serif',
color: '#4B5563',
letterSpacing: '-0.01em',
}}
>
#{subtitle}
</div>
</div>
</div>,
{
width,
height,
fonts: [
{
name: 'Open Sans',
data: (await opensansRegular)!,
weight: 700,
style: 'normal',
},
{
name: 'Open Sans',
data: (await opensansBold)!,
weight: 900,
style: 'normal',
},
],
}
);
const resvg = new Resvg(svg, {
fitTo: { mode: 'width', value: width },
});
return resvg.render().asPng();
}
import { createServerFileRoute } from '@tanstack/react-start/server'
import { getSupabaseServerClient } from '~/servers/supabase-server';
import { generateNoteOgImage } from '~/utils/generateOpengraphImage';
export const ServerRoute = createServerFileRoute('/api/og/$linkId').methods({
GET: async ({ params }) => {
const supabase = getSupabaseServerClient()
async function getNoteDetails(link: string) {
// Check p_journals first
const { data: journal } = await supabase
.from('p_journals')
.select('name')
.eq('share_link', link)
.single()
if (journal?.name) {
return journal.name
}
// If not found, check p_trade_notes
const { data: tradeNote } = await supabase
.from('p_trade_notes')
.select('id')
.eq('share_link', link)
.single()
return tradeNote ? 'Trade Note' : 'Shared Note'
}
const linkId = params.linkId;
const title = await getNoteDetails(linkId)
const image = await generateNoteOgImage({ title, subtitle: linkId });
return new Response(image, {
headers: {
'Content-Type': 'image/png',
'Cache-Control': 'public, max-age=31536000, immutable',
},
});
},
})
export const seo = ({
title,
description,
keywords,
image,
}: {
title: string;
description?: string;
image?: string;
keywords?: string;
}) => {
const tags = [
{ title },
{ name: 'description', content: description },
{ name: 'keywords', content: keywords },
{ name: 'twitter:title', content: title },
{ name: 'twitter:description', content: description },
{ name: 'twitter:creator', content: '@trycaltho' },
{ name: 'twitter:site', content: 'Caltho' },
{ name: 'og:type', content: 'website' },
{ name: 'og:title', content: title },
{ name: 'og:description', content: description },
...(image
? [
{ name: 'twitter:image', content: image },
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'og:image', content: image },
]
: []),
];
return tags;
};
import { Card, CardContent, CardHeader, CardTitle } from '@caltho/ui/components/card';
import { ScrollArea } from '@caltho/ui/components/scroll-area';
import { createFileRoute } from '@tanstack/react-router';
import { JSONContent } from '@tiptap/core';
import { format } from 'date-fns';
import { ArrowRight, ExternalLink, FileText, Sparkles } from 'lucide-react';
import { Badge } from '@caltho/ui/components/badge';
import { useQuery } from '@tanstack/react-query';
import TailwindAdvancedEditor from '~/components/editor/advanced-editor';
import { seo } from '~/utils/seo';
import { Caltho } from '~/components/logo';
import Spinner from '~/components/Spinner';
import { getSharedContentOptions, getNoteTitleOptions } from '~/servers/share-server';
export const Route = createFileRoute('/share/$linkId')({
component: SharePage,
loader: async ({ params, context }) => {
// Pre-fetch shared content and note title for metadata
context.queryClient.prefetchQuery(getSharedContentOptions(params.linkId));
context.queryClient.prefetchQuery(getNoteTitleOptions(params.linkId));
return {};
},
head: ({ params }) => {
const fullTitle = 'Shared Note - Caltho';
const description = 'Shared note from Caltho';
const ogUrl = `${process.env.VITE_SITE_URL || 'https://caltho.com'}/api/og/${params.linkId}`;
return {
meta: [
...seo({
title: fullTitle,
description: description,
image: ogUrl,
}),
// Additional specific meta tags
{ property: 'og:image:width', content: '1200' },
{ property: 'og:image:height', content: '630' },
{ property: 'og:image:alt', content: 'Shared Note - Caltho' },
],
};
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment