@writely/preview
Version:
Lightning-fast development server with live preview for Writely blogs. Hot reload, file watching, and instant feedback for the best development experience.
67 lines (66 loc) • 2.19 kB
JSX
import { access, readFile } from "fs/promises";
import { MDXRemote } from "next-mdx-remote/rsc";
import { getTheme } from "@writely/core";
import { notFound } from "next/navigation";
import path from "path";
import { processMDXContent } from "@writely/mdx";
// Helper function to find MDX file based on slug
async function findMDXFile(slug) {
const cwd = process.cwd();
// Try different possible paths
const possiblePaths = [
// Root level MDX files
path.join(cwd, ...slug, "index.mdx"),
path.join(cwd, ...slug) + ".mdx",
// Direct file at root
path.join(cwd, slug[0] + ".mdx"),
// Nested structure
path.join(cwd, ...slug.slice(0, -1), slug[slug.length - 1] + ".mdx"),
];
for (const filePath of possiblePaths) {
try {
await access(filePath);
return filePath;
}
catch {
// File doesn't exist, try next path
continue;
}
}
return null;
}
export default async function Page({ params, config }) {
const slug = params.slug || [];
// Find the MDX file
const contentPath = await findMDXFile(slug);
if (!contentPath) {
notFound();
}
try {
const content = await readFile(contentPath, "utf-8");
// Use our advanced MDX processing
const { source, frontmatter } = await processMDXContent(content, {
syntaxHighlighting: {
theme: "github-light-default",
themes: {
light: "github-light-default",
dark: "github-dark-default",
},
},
});
// Get the theme component
const ThemeComponent = getTheme(config.theme || "nova");
return (<ThemeComponent config={config}>
<article className="prose dark:prose-invert max-w-none">
<h1>{frontmatter.title}</h1>
{frontmatter.description && (<p className="text-lg text-muted-foreground">
{frontmatter.description}
</p>)}
{await MDXRemote({ source })}
</article>
</ThemeComponent>);
}
catch (error) {
notFound();
}
}