Skip to content

Commit

Permalink
feat: simple og image (#176)
Browse files Browse the repository at this point in the history
* feat: simple og image

* feat: simple og image

* fix: redirect to thread landing on homepage

* fix: link to terms
  • Loading branch information
gaboesquivel authored Apr 14, 2024
1 parent b8df4fb commit 9a6c866
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 10 deletions.
1 change: 0 additions & 1 deletion apps/masterbots.ai/.env.local
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ NEXT_PUBLIC_APP_ENV=test
# AUTH_REDIRECT_PROXY_URL=https://YOURAPP.vercel.app/api/auth

# https://hasura.io/learn/graphql/hasura-authentication/integrations/nextjs-auth/
NEXTAUTH_URL=http://localhost:3000
AUTH_SECRET=bb755cba466058b2e6a195541468e84c

JWT_TOKEN_EXPIRATION=2630016
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ThreadAccordion } from '@/components/shared/thread-accordion'
import { CategoryTabs } from '@/components/shared/category-tabs/category-tabs'
import { SearchInput } from '@/components/shared/search-input'

export { generateMbMetadata as generateMetadata } from '@/lib/metadata'

export default async function ThreadPage({ params }: ThreadPageProps) {
const categories = await getCategories()
const thread = await getThread({
Expand Down
16 changes: 14 additions & 2 deletions apps/masterbots.ai/app/(browse)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { ThreadList } from '@/components/shared/thread-list'
import { CategoryTabs } from '@/components/shared/category-tabs/category-tabs'
import { SearchInput } from '@/components/shared/search-input'
import { getBrowseThreads, getCategories } from '@/services/hasura'
import { getBrowseThreads, getCategories, getThread } from '@/services/hasura'
import { Card } from '@/components/ui/card'
import { decodeQuery } from '@/lib/url'
import { permanentRedirect } from 'next/navigation'
import { getThreadLink } from '@/lib/threads'

export default async function HomePage({ searchParams }: HomePageProps) {
if (searchParams.threadId) {
const thread = await getThread({ threadId: searchParams.threadId })
permanentRedirect(getThreadLink({ thread }))
}

const categories = await getCategories()
const query = searchParams.query ? decodeQuery(searchParams.query) : null
const limit = searchParams.limit ? parseInt(searchParams.limit) : 20
Expand Down Expand Up @@ -44,5 +51,10 @@ export default async function HomePage({ searchParams }: HomePageProps) {
}

interface HomePageProps {
searchParams?: { query: string; page: string; limit: string }
searchParams?: {
query: string
page: string
limit: string
threadId: string
}
}
58 changes: 58 additions & 0 deletions apps/masterbots.ai/app/og/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ImageResponse } from '@vercel/og'
import { NextRequest } from 'next/server'
import { GeistMono } from 'geist/font/mono' // Import the GeistMono font

export const runtime = 'edge'

export async function GET(req: NextRequest) {
const { searchParams } = req.nextUrl
const postTitle = searchParams.get('title')

// You may need to convert GeistMono or fetch it as ArrayBuffer if needed
// const font = GeistMono; // Assuming GeistMono can be directly used, modify as needed

return new ImageResponse(
(
<div
style={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
justifyContent: 'center',
background: '#110f0f'
}}
>
<div
style={{
marginLeft: 190,
marginRight: 190,
display: 'flex',
fontSize: 130,
fontFamily: GeistMono.className,
letterSpacing: '-0.05em',
fontStyle: 'normal',
color: 'white',
lineHeight: '120px',
whiteSpace: 'pre-wrap'
}}
>
{postTitle}
</div>
</div>
),
{
width: 1920,
height: 1080
// Optionally, if font needs to be loaded as data
// fonts: [
// {
// name: 'GeistMono',
// data: font, // Assuming font data is handled accordingly
// style: 'normal'
// }
// ]
}
)
}
9 changes: 5 additions & 4 deletions apps/masterbots.ai/components/layout/footer-ct.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Link from 'next/link'
import type { ElementType } from 'react'

export default function FooterCT({ nonFooterTag }: { nonFooterTag?: boolean }) {
Expand All @@ -24,13 +25,13 @@ export default function FooterCT({ nonFooterTag }: { nonFooterTag?: boolean }) {
>
robohash.org
</a>
{' • '}
<a
<Link
shallow
className="text-primary underline focus-within:underline"
href="/terms-n-policies"
href="/terms"
>
terms & policies
</a>
</Link>
</span>
</Footer>
)
Expand Down
1 change: 0 additions & 1 deletion apps/masterbots.ai/components/routes/c/chat-input-new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export interface ChatInputProps
showReload?: boolean
placeholder: string
className?: string
showSubmitButton: boolean
}

export function ChatInputNew({
Expand Down
48 changes: 48 additions & 0 deletions apps/masterbots.ai/lib/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { getThread } from '@/services/hasura';
import type { Metadata } from 'next';
import { format } from 'date-fns';
import { getThreadLink } from './threads';

export async function generateMbMetadata({
params,
}): Promise<Metadata | undefined> {
const thread = await getThread({threadId: params.threadId})
if (!thread) return


const firstQuestion=
thread.messages.find(m => m.role === 'user')?.content || 'not found'
const firstResponse =
thread.messages.find(m => m.role === 'assistant')?.content || 'not found'

const data = {
title: firstQuestion,
publishedAt: thread.updatedAt, // format(thread.updatedAt, 'MMMM dd, yyyy'),
summary: firstResponse,
image: `https://alpha.masterbots.ai/og?title=${encodeURIComponent(firstQuestion)}`,
pathname: getThreadLink({thread:thread, chat:false})
}

return {
title:data.title,
description:data.summary,
openGraph: {
title:data.title,
description:data.summary,
type: 'article',
publishedTime: data.publishedAt,
url: `https://alpha.masterbots.ai/${data.pathname}`,
images: [
{
url: data.image,
},
],
},
twitter: {
card: 'summary_large_image',
title:data.title,
description:data.summary,
images: [data.image],
},
};
}
2 changes: 1 addition & 1 deletion apps/masterbots.ai/lib/threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,6 @@ export function getAllUserMessagesAsStringArray(
return cleanMessages.join(', ')
}

export function getThreadLink({chat=false, thread}:{chat:boolean, thread: Thread}){
export function getThreadLink({chat=false, thread}:{chat?:boolean, thread: Thread}){
return chat ? `/c/${toSlug(thread.chatbot.name)}/${thread.threadId}` : `/${toSlug(thread.chatbot.categories[0]?.category.name)}/${thread.threadId}`
}
2 changes: 1 addition & 1 deletion apps/masterbots.ai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@supabase/ssr": "^0.1.0",
"@tanstack/react-query": "^5.29.0",
"@vercel/analytics": "^1.1.1",
"@vercel/og": "^0.5.20",
"@vercel/og": "^0.6.2",
"ai": "^2.2.25",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
Expand Down
Binary file modified bun.lockb
Binary file not shown.

0 comments on commit 9a6c866

Please sign in to comment.