created system to create post-specific components

This commit is contained in:
Waleed Latif
2026-01-22 21:47:36 -08:00
parent 30df76ba60
commit 821d45c70a
5 changed files with 34 additions and 9 deletions

View File

@@ -5,6 +5,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/emcn'
import { FAQ } from '@/lib/blog/faq'
import { getAllPostMeta, getPostBySlug, getRelatedPosts } from '@/lib/blog/registry'
import { buildArticleJsonLd, buildBreadcrumbJsonLd, buildPostMetadata } from '@/lib/blog/seo'
import { getBaseUrl } from '@/lib/core/utils/urls'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { BackLink } from '@/app/(landing)/studio/[slug]/back-link'
import { ShareButton } from '@/app/(landing)/studio/[slug]/share-button'
@@ -99,7 +100,7 @@ export default async function Page({ params }: { params: Promise<{ slug: string
</div>
))}
</div>
<ShareButton url={`https://sim.ai/studio/${slug}`} title={post.title} />
<ShareButton url={`${getBaseUrl()}/studio/${slug}`} title={post.title} />
</div>
</div>
</div>

View File

@@ -14,12 +14,16 @@ export function ShareButton({ url, title }: ShareButtonProps) {
const [copied, setCopied] = useState(false)
const handleCopyLink = async () => {
await navigator.clipboard.writeText(url)
setCopied(true)
setTimeout(() => {
setCopied(false)
try {
await navigator.clipboard.writeText(url)
setCopied(true)
setTimeout(() => {
setCopied(false)
setOpen(false)
}, 1000)
} catch {
setOpen(false)
}, 1000)
}
}
const handleShareTwitter = () => {

View File

@@ -0,0 +1 @@
export { DiffControlsDemo } from './components/diff-controls-demo'

View File

@@ -2,10 +2,8 @@ import clsx from 'clsx'
import Image from 'next/image'
import type { MDXRemoteProps } from 'next-mdx-remote/rsc'
import { CodeBlock } from '@/lib/blog/code'
import { DiffControlsDemo } from '@/content/blog/v0-5/components/diff-controls-demo'
export const mdxComponents: MDXRemoteProps['components'] = {
DiffControlsDemo,
img: (props: any) => (
<Image
src={props.src}

View File

@@ -10,6 +10,8 @@ import type { BlogMeta, BlogPost, TagWithCount } from '@/lib/blog/schema'
import { AuthorSchema, BlogFrontmatterSchema } from '@/lib/blog/schema'
import { AUTHORS_DIR, BLOG_DIR, byDateDesc, ensureContentDirs, toIsoDate } from '@/lib/blog/utils'
const postComponentsRegistry: Record<string, Record<string, React.ComponentType>> = {}
let cachedMeta: BlogMeta[] | null = null
let cachedAuthors: Record<string, any> | null = null
@@ -99,6 +101,21 @@ export async function getAllTags(): Promise<TagWithCount[]> {
.sort((a, b) => b.count - a.count || a.tag.localeCompare(b.tag))
}
async function loadPostComponents(slug: string): Promise<Record<string, React.ComponentType>> {
if (postComponentsRegistry[slug]) {
return postComponentsRegistry[slug]
}
try {
const postComponents = await import(`@/content/blog/${slug}/components`)
postComponentsRegistry[slug] = postComponents
return postComponents
} catch {
postComponentsRegistry[slug] = {}
return {}
}
}
export async function getPostBySlug(slug: string): Promise<BlogPost> {
const meta = await scanFrontmatters()
const found = meta.find((m) => m.slug === slug)
@@ -107,9 +124,13 @@ export async function getPostBySlug(slug: string): Promise<BlogPost> {
const raw = await fs.readFile(mdxPath, 'utf-8')
const { content, data } = matter(raw)
const fm = BlogFrontmatterSchema.parse(data)
const postComponents = await loadPostComponents(slug)
const mergedComponents = { ...mdxComponents, ...postComponents }
const compiled = await compileMDX({
source: content,
components: mdxComponents as any,
components: mergedComponents as any,
options: {
parseFrontmatter: false,
mdxOptions: {