Handle SSR for static pages

feat/roadmap-slug
Kamran Ahmed 10 months ago
parent 33af126728
commit bd01586e8e
  1. 13
      src/lib/guide.ts
  2. 13
      src/lib/link-group.ts
  3. 6
      src/lib/question-group.ts
  4. 13
      src/lib/video.ts
  5. 3
      src/pages/[roadmapId]/[...topicId].astro
  6. 27
      src/pages/g/[linkGroupId]/[linkId].astro
  7. 21
      src/pages/guides/[guideId].astro
  8. 27
      src/pages/questions/[questionGroupId].astro
  9. 21
      src/pages/videos/[videoId].astro

@ -48,7 +48,7 @@ export async function getAllGuides(): Promise<GuideFileType[]> {
'/src/data/guides/*.md',
{
eager: true,
}
},
);
const guideFiles = Object.values(guides);
@ -60,6 +60,15 @@ export async function getAllGuides(): Promise<GuideFileType[]> {
return enrichedGuides.sort(
(a, b) =>
new Date(b.frontmatter.date).valueOf() -
new Date(a.frontmatter.date).valueOf()
new Date(a.frontmatter.date).valueOf(),
);
}
export async function getGuideById(id: string): Promise<GuideFileType> {
const guide = await import(`/src/data/guides/${id}.md`);
return {
...guide,
id: guidePathToId(guide.file),
};
}

@ -29,7 +29,7 @@ export async function getAllLinkGroups(): Promise<LinkGroupFileType[]> {
'/src/data/link-groups/*.md',
{
eager: true,
}
},
);
return Object.values(linkGroups).map((linkGroupFile) => ({
@ -37,3 +37,14 @@ export async function getAllLinkGroups(): Promise<LinkGroupFileType[]> {
id: linkGroupPathToId(linkGroupFile.file),
}));
}
export async function getLinkGroupById(
groupId: string,
): Promise<LinkGroupFileType> {
const linkGroup = await import(`/src/data/link-groups/${groupId}.md`);
return {
...linkGroup,
id: linkGroupPathToId(linkGroup.file),
};
}

@ -117,6 +117,12 @@ export async function getAllQuestionGroups(): Promise<QuestionGroupType[]> {
.sort((a, b) => a.frontmatter.order - b.frontmatter.order);
}
export async function getQuestionGroupById(id: string) {
const questionGroups = await getAllQuestionGroups();
return questionGroups.find((group) => group.id === id);
}
export async function getQuestionGroupsByIds(
ids: string[],
): Promise<{ id: string; title: string; description: string }[]> {

@ -47,7 +47,7 @@ export async function getAllVideos(): Promise<VideoFileType[]> {
'/src/data/videos/*.md',
{
eager: true,
}
},
);
const videoFiles = Object.values(videos);
@ -59,6 +59,15 @@ export async function getAllVideos(): Promise<VideoFileType[]> {
return enrichedVideos.sort(
(a, b) =>
new Date(b.frontmatter.date).valueOf() -
new Date(a.frontmatter.date).valueOf()
new Date(a.frontmatter.date).valueOf(),
);
}
export async function getVideoById(id: string): Promise<VideoFileType> {
const video = await import(`/src/data/videos/${id}.md`);
return {
...video,
id: videoPathToId(video.file),
};
}

@ -12,6 +12,9 @@ const topicSlug = `/${roadmapId}/${topicId}`;
const topicPathMapping = await getRoadmapTopicFiles();
const topicDetails = topicPathMapping[topicSlug];
if (!topicDetails) {
return Astro.redirect('/404');
}
const { file } = topicDetails;

@ -1,30 +1,13 @@
---
import BaseLayout from '../../../layouts/BaseLayout.astro';
import SkeletonLayout from '../../../layouts/SkeletonLayout.astro';
import { getAllLinkGroups } from '../../../lib/link-group';
export async function getStaticPaths() {
const linkGroups = await getAllLinkGroups();
return linkGroups.flatMap((linkGroup) => {
const linkGroupLinks = linkGroup.frontmatter;
return Object.keys(linkGroupLinks).map((slug) => {
return {
params: {
linkGroupId: linkGroup.id,
linkId: slug,
},
props: {
linkGroup,
},
};
});
});
}
import { getLinkGroupById } from '../../../lib/link-group';
const { linkId } = Astro.params;
const { linkGroup } = Astro.props;
const linkGroup = await getLinkGroupById(linkId!).catch(() => null);
if (!linkGroup) {
return Astro.redirect('/404');
}
const fullUrl = linkGroup.frontmatter[linkId!];
---

@ -2,23 +2,14 @@
import GuideHeader from '../../components/GuideHeader.astro';
import MarkdownFile from '../../components/MarkdownFile.astro';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { getAllGuides,GuideFileType } from '../../lib/guide';
import { getGuideById } from '../../lib/guide';
export interface Props {
guide: GuideFileType;
}
export async function getStaticPaths() {
const guides = await getAllGuides();
return guides.map((guide) => ({
params: { guideId: guide.id },
props: { guide },
}));
const { guideId } = Astro.params;
const guide = await getGuideById(guideId).catch(() => null);
if (!guide) {
return Astro.redirect('/404');
}
const { guideId } = Astro.params;
const { guide } = Astro.props;
const { frontmatter: guideData } = guide;
---
@ -30,7 +21,7 @@ const { frontmatter: guideData } = guide;
>
<GuideHeader guide={guide} />
<div class='py-5 sm:py-10 max-w-[700px] mx-auto'>
<div class='mx-auto max-w-[700px] py-5 sm:py-10'>
<MarkdownFile>
<guide.Content />
</MarkdownFile>

@ -8,24 +8,15 @@ import { QuestionsList } from '../../components/Questions/QuestionsList';
import {
getAllQuestionGroups,
type QuestionGroupType,
getQuestionGroupById,
} from '../../lib/question-group';
export interface Props {
questionGroup: QuestionGroupType;
const { questionGroupId } = Astro.params;
const questionGroup = await getQuestionGroupById(questionGroupId);
if (!questionGroup) {
return Astro.redirect('/404');
}
export async function getStaticPaths() {
const questionGroups = await getAllQuestionGroups();
return questionGroups.map((questionGroup) => {
return {
params: { questionGroupId: questionGroup.id },
props: { questionGroup },
};
});
}
const { questionGroup } = Astro.props;
const { frontmatter } = questionGroup;
---
@ -38,24 +29,24 @@ const { frontmatter } = questionGroup;
>
<div class='flex bg-gray-50 pb-14 pt-4 sm:pb-16 sm:pt-8'>
<div class='container !max-w-[740px]'>
<div class='mb-3 sm:mb-5 mt-2 text-left sm:text-center sm:mt-8'>
<div class='mb-3 mt-2 text-left sm:mb-5 sm:mt-8 sm:text-center'>
<div class='mb-2 md:mb-6'>
<a
href='/questions'
class='group rounded-md text-sm font-medium text-gray-400 hover:text-gray-800 transition-colors duration-200'
class='group rounded-md text-sm font-medium text-gray-400 transition-colors duration-200 hover:text-gray-800'
>
<span
class='inline-block transform transition-transform group-hover:translate-x-[-2px]'
>
&larr;
</span>
Back to all Questions
Back to all Questions
</a>
</div>
<h1 class='mb-1 text-2xl font-bold sm:mb-5 sm:text-5xl'>
{frontmatter.title}
</h1>
<p class='hidden sm:block text-xl text-gray-500'>
<p class='hidden text-xl text-gray-500 sm:block'>
{frontmatter.description}
</p>
</div>

@ -1,23 +1,14 @@
---
import VideoHeader from '../../components/VideoHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro';
import { getAllVideos,VideoFileType } from '../../lib/video';
import { getVideoById } from '../../lib/video';
export interface Props {
video: VideoFileType;
}
export async function getStaticPaths() {
const videos = await getAllVideos();
const { videoId } = Astro.params;
return videos.map((video) => ({
params: { videoId: video.id },
props: { video },
}));
const video = await getVideoById(videoId).catch(() => null);
if (!video) {
return Astro.redirect('/404');
}
const { videoId } = Astro.params;
const { video } = Astro.props;
---
<BaseLayout
@ -29,7 +20,7 @@ const { video } = Astro.props;
<div class='bg-gray-50 py-5 sm:py-10'>
<div
class='container prose prose-code:bg-transparent prose-h2:text-3xl prose-h2:mt-4 prose-h2:mb-2 prose-h3:mt-2 prose-img:mt-1'
class='container prose prose-h2:mb-2 prose-h2:mt-4 prose-h2:text-3xl prose-h3:mt-2 prose-code:bg-transparent prose-img:mt-1'
>
<video.Content />
</div>

Loading…
Cancel
Save