--- import CaptchaScripts from '../../components/Captcha/CaptchaScripts.astro'; import FAQs from '../../components/FAQs/FAQs.astro'; import FrameRenderer from '../../components/FrameRenderer/FrameRenderer.astro'; import MarkdownFile from '../../components/MarkdownFile.astro'; import RoadmapHeader from '../../components/RoadmapHeader.astro'; import ShareIcons from '../../components/ShareIcons/ShareIcons.astro'; import TopicOverlay from '../../components/TopicOverlay/TopicOverlay.astro'; import UpcomingForm from '../../components/UpcomingForm.astro'; import BaseLayout from '../../layouts/BaseLayout.astro'; import { generateArticleSchema, generateFAQSchema } from '../../lib/jsonld-schema'; import { getRoadmapIds, RoadmapFrontmatter } from '../../lib/roadmap'; export async function getStaticPaths() { const roadmapIds = await getRoadmapIds(); return roadmapIds.map((roadmapId) => ({ params: { roadmapId }, })); } interface Params extends Record<string, string | undefined> { roadmapId: string; } const { roadmapId } = Astro.params as Params; const roadmapFile = await import(`../../roadmaps/${roadmapId}/${roadmapId}.md`); const { faqs: roadmapFAQs = [] } = await import(`../../roadmaps/${roadmapId}/faqs.astro`); const roadmapData = roadmapFile.frontmatter as RoadmapFrontmatter; let jsonLdSchema = []; if (roadmapData.schema) { const roadmapSchema = roadmapData.schema; jsonLdSchema.push( generateArticleSchema({ url: `https://roadmap.sh/${roadmapId}`, headline: roadmapSchema.headline, description: roadmapSchema.description, datePublished: roadmapSchema.datePublished, dateModified: roadmapSchema.dateModified, imageUrl: roadmapSchema.imageUrl, }) ); } if (roadmapFAQs.length) { jsonLdSchema.push(generateFAQSchema(roadmapFAQs)); } --- <BaseLayout permalink={`/${roadmapId}`} title={roadmapData?.seo?.title} description={roadmapData.seo.description} keywords={roadmapData.seo.keywords} sponsor={roadmapData.sponsor} noIndex={roadmapData.isUpcoming} jsonLd={jsonLdSchema} > <!-- Preload the font being used in the renderer --> <link rel='preload' href='/fonts/balsamiq.woff2' as='font' type='font/woff2' crossorigin slot='after-header' /> <RoadmapHeader title={roadmapData.title} description={roadmapData.description} note={roadmapData.note} roadmapId={roadmapId} hasTopics={roadmapData.hasTopics} isUpcoming={roadmapData.isUpcoming} /> <div class='bg-gray-50 py-4 sm:py-12'> { !roadmapData.isUpcoming && roadmapData.jsonUrl && ( <div class='max-w-[1000px] container relative'> <ShareIcons description={roadmapData.featuredDescription} pageUrl={`https://roadmap.sh/${roadmapId}`} /> <TopicOverlay roadmapId={roadmapId} /> <FrameRenderer roadmapId={roadmapId} jsonUrl={roadmapData.jsonUrl} dimensions={roadmapData.dimensions} /> </div> ) } { !roadmapData.isUpcoming && !roadmapData.jsonUrl && ( <div class='mt-0 sm:-mt-6'> <MarkdownFile> <roadmapFile.Content /> </MarkdownFile> </div> ) } {roadmapData.isUpcoming && <UpcomingForm />} <FAQs faqs={roadmapFAQs} /> <CaptchaScripts slot='after-footer' /> </div> </BaseLayout>