Refactor related guides functionality (#7800)

pull/7804/head
Kamran Ahmed 5 days ago committed by GitHub
parent 9d65c49b8d
commit 6f38dcccb8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 8
      src/components/Guide/GuideContent.astro
  2. 53
      src/components/GuideHeader.astro
  3. 7
      src/components/GuideListItem.astro
  4. 22
      src/components/Questions/QuestionGuide.astro
  5. 9
      src/data/guides/backend-developer-skills.md
  6. 9
      src/data/guides/backend-developer-tools.md
  7. 9
      src/data/guides/backend-frameworks.md
  8. 13
      src/data/guides/backend-job-description.md
  9. 9
      src/data/guides/backend-languages.md
  10. 9
      src/data/guides/backend-project-ideas.md
  11. 9
      src/data/guides/backend-technologies.md
  12. 10
      src/data/guides/devops-automation-tools.md
  13. 9
      src/data/guides/devops-automation.md
  14. 9
      src/data/guides/devops-best-practices.md
  15. 9
      src/data/guides/devops-career-path.md
  16. 9
      src/data/guides/devops-lifecycle.md
  17. 9
      src/data/guides/devops-principles.md
  18. 9
      src/data/guides/devops-shift-left-testing.md
  19. 9
      src/data/guides/devops-skills.md
  20. 9
      src/data/guides/devops-vs-full-stack.md
  21. 9
      src/data/guides/frontend-developer-skills.md
  22. 9
      src/data/guides/frontend-frameworks.md
  23. 13
      src/data/guides/frontend-job-description.md
  24. 9
      src/data/guides/frontend-languages.md
  25. 9
      src/data/guides/frontend-vs-backend-ai.md
  26. 9
      src/data/guides/frontend-web-developer-portfolio.md
  27. 4
      src/data/guides/full-stack-job-description.md
  28. 9
      src/data/guides/how-to-become-devops-engineer.md
  29. 9
      src/data/guides/how-to-become-frontend-developer.md
  30. 9
      src/data/question-groups/backend/backend.md
  31. 9
      src/data/question-groups/frontend/frontend.md
  32. 49
      src/lib/guide.ts
  33. 24
      src/lib/question-group.ts
  34. 9
      src/pages/backend/developer-skills.astro
  35. 6
      src/pages/backend/developer-tools.astro
  36. 6
      src/pages/backend/frameworks.astro
  37. 2
      src/pages/backend/job-description.astro
  38. 6
      src/pages/backend/languages.astro
  39. 6
      src/pages/backend/project-ideas.astro
  40. 6
      src/pages/backend/technologies.astro
  41. 6
      src/pages/devops/automation-tools.astro
  42. 6
      src/pages/devops/automation.astro
  43. 6
      src/pages/devops/best-practices.astro
  44. 6
      src/pages/devops/career-path.astro
  45. 6
      src/pages/devops/devops-engineer.astro
  46. 8
      src/pages/devops/devops-vs-sre.astro
  47. 10
      src/pages/devops/how-to-become-devops-engineer.astro
  48. 8
      src/pages/devops/lifecycle.astro
  49. 8
      src/pages/devops/principles.astro
  50. 8
      src/pages/devops/shift-left-testing.astro
  51. 10
      src/pages/devops/skills.astro
  52. 10
      src/pages/devops/vs-full-stack.astro
  53. 11
      src/pages/frontend/developer-skills.astro
  54. 11
      src/pages/frontend/frameworks.astro
  55. 9
      src/pages/frontend/how-to-become-frontend-developer.astro
  56. 3
      src/pages/frontend/job-description.astro
  57. 11
      src/pages/frontend/languages.astro
  58. 9
      src/pages/frontend/vs-backend-ai.astro
  59. 9
      src/pages/frontend/web-developer-portfolio.astro
  60. 9
      src/pages/full-stack/developer-skills.astro
  61. 9
      src/pages/full-stack/job-description.astro
  62. 9
      src/pages/full-stack/vs-backend.astro
  63. 9
      src/pages/full-stack/vs-software-engineer.astro
  64. 6
      src/pages/guides/[guideId].astro
  65. 10
      src/pages/java/developer-skills.astro

@ -2,7 +2,6 @@
import { getGuideTableOfContent, type GuideFileType } from '../../lib/guide'; import { getGuideTableOfContent, type GuideFileType } from '../../lib/guide';
import MarkdownFile from '../MarkdownFile.astro'; import MarkdownFile from '../MarkdownFile.astro';
import { TableOfContent } from '../TableOfContent/TableOfContent'; import { TableOfContent } from '../TableOfContent/TableOfContent';
import { replaceVariables } from '../../lib/markdown';
import { RelatedGuides } from './RelatedGuides'; import { RelatedGuides } from './RelatedGuides';
interface Props { interface Props {
@ -16,8 +15,7 @@ const tableOfContent = getGuideTableOfContent(allHeadings);
const showTableOfContent = tableOfContent.length > 0; const showTableOfContent = tableOfContent.length > 0;
const showRelatedGuides = const showRelatedGuides =
guide?.frontmatter?.relatedGuides && guide?.relatedGuides && Object.keys(guide?.relatedGuides).length > 0;
Object.keys(guide?.frontmatter?.relatedGuides).length > 0;
const { frontmatter: guideFrontmatter, author } = guide; const { frontmatter: guideFrontmatter, author } = guide;
--- ---
@ -27,7 +25,7 @@ const { frontmatter: guideFrontmatter, author } = guide;
<div class='bg-gradient-to-r from-gray-50 py-0 lg:col-start-3 lg:col-end-4 lg:row-start-1'> <div class='bg-gradient-to-r from-gray-50 py-0 lg:col-start-3 lg:col-end-4 lg:row-start-1'>
<RelatedGuides <RelatedGuides
relatedTitle={guideFrontmatter?.relatedTitle} relatedTitle={guideFrontmatter?.relatedTitle}
relatedGuides={guideFrontmatter?.relatedGuides || {}} relatedGuides={guide?.relatedGuides || {}}
client:load client:load
/> />
<TableOfContent toc={tableOfContent} client:load /> <TableOfContent toc={tableOfContent} client:load />
@ -45,7 +43,7 @@ const { frontmatter: guideFrontmatter, author } = guide;
> >
<MarkdownFile> <MarkdownFile>
<h1 class='mb-3 text-balance text-4xl font-bold'> <h1 class='mb-3 text-balance text-4xl font-bold'>
{replaceVariables(guideFrontmatter.title)} {guideFrontmatter.title}
</h1> </h1>
<p class='my-0 flex items-center justify-start text-sm text-gray-400'> <p class='my-0 flex items-center justify-start text-sm text-gray-400'>
<a <a

@ -1,53 +0,0 @@
---
import type { GuideFileType } from '../lib/guide';
import { replaceVariables } from '../lib/markdown';
export interface Props {
guide: GuideFileType;
}
const { guide } = Astro.props;
const { frontmatter, author } = guide;
return undefined;
---
<div class='border-b bg-white py-5 sm:py-12'>
<div class='container text-left sm:text-center'>
<p
class='hidden items-center justify-start text-gray-400 sm:flex sm:justify-center'
>
{
author?.frontmatter && (
<>
<a
href={`/authors/${author.id}`}
class='inline-flex items-center font-medium hover:text-gray-600 hover:underline'
>
<img
alt={author.frontmatter.name}
src={author.frontmatter.imageUrl}
class='mr-2 inline h-5 w-5 rounded-full'
/>
{author.frontmatter.name}
</a>
<span class='mx-1.5'>&middot;</span>
</>
)
}
<span class='capitalize'>{frontmatter.type} Guide</span>
<span class='mx-1.5'>&middot;</span>
<a
class='text-blue-400 hover:text-blue-500 hover:underline'
href={`https://github.com/kamranahmedse/developer-roadmap/tree/master/src/data/guides/${guide.id}.md`}
target='_blank'>Improve this Guide</a
>
</p>
<h1 class='my-0 text-balance text-2xl font-bold sm:my-3.5 sm:text-5xl'>
{replaceVariables(frontmatter.title)}
</h1>
<p class='hidden text-xl text-gray-400 sm:block'>
{replaceVariables(frontmatter.description)}
</p>
</div>
</div>

@ -1,7 +1,6 @@
--- ---
import type { GuideFileType, GuideFrontmatter } from '../lib/guide'; import type { GuideFileType, GuideFrontmatter } from '../lib/guide';
import { replaceVariables } from '../lib/markdown'; import { type QuestionGroupType } from '../lib/question-group';
import { QuestionGroupType } from '../lib/question-group';
export interface Props { export interface Props {
guide: GuideFileType | QuestionGroupType; guide: GuideFileType | QuestionGroupType;
@ -38,7 +37,7 @@ if (isQuestionGroupType(guide)) {
<span <span
class='text-sm transition-transform group-hover:translate-x-2 md:text-base' class='text-sm transition-transform group-hover:translate-x-2 md:text-base'
> >
{replaceVariables(frontmatter.title)} {frontmatter.title}
{ {
frontmatter.isNew && ( frontmatter.isNew && (
@ -46,7 +45,7 @@ if (isQuestionGroupType(guide)) {
New New
<span class='hidden sm:inline'> <span class='hidden sm:inline'>
&middot; &middot;
{new Date(frontmatter.date).toLocaleString('default', { {new Date(frontmatter.date || '').toLocaleString('default', {
month: 'long', month: 'long',
})} })}
</span> </span>

@ -1,15 +1,11 @@
--- ---
import { import { getGuideTableOfContent, type HeadingGroupType } from '../../lib/guide';
getGuideTableOfContent, import { markdownToHtml } from '../../lib/markdown';
type GuideFileType, import { type QuestionGroupType } from '../../lib/question-group';
HeadingGroupType, import { RelatedGuides } from '../Guide/RelatedGuides';
} from '../../lib/guide';
import MarkdownFile from '../MarkdownFile.astro'; import MarkdownFile from '../MarkdownFile.astro';
import { TableOfContent } from '../TableOfContent/TableOfContent'; import { TableOfContent } from '../TableOfContent/TableOfContent';
import { markdownToHtml, replaceVariables } from '../../lib/markdown';
import { QuestionGroupType } from '../../lib/question-group';
import { QuestionsList } from './QuestionsList'; import { QuestionsList } from './QuestionsList';
import { RelatedGuides } from '../Guide/RelatedGuides';
interface Props { interface Props {
questionGroup: QuestionGroupType; questionGroup: QuestionGroupType;
@ -22,14 +18,12 @@ const tableOfContent: HeadingGroupType[] = [
...getGuideTableOfContent(allHeadings), ...getGuideTableOfContent(allHeadings),
{ {
depth: 2, depth: 2,
title: 'Test with Flashcards',
children: [], children: [],
slug: 'test-with-flashcards', slug: 'test-with-flashcards',
text: 'Test yourself with Flashcards', text: 'Test yourself with Flashcards',
}, },
{ {
depth: 2, depth: 2,
title: 'Questions List',
children: [ children: [
{ {
depth: 2, depth: 2,
@ -68,7 +62,7 @@ const { frontmatter: guideFrontmatter, author } = questionGroup;
<div class='bg-gradient-to-r from-gray-50 py-0 lg:col-start-3 lg:col-end-4 lg:row-start-1'> <div class='bg-gradient-to-r from-gray-50 py-0 lg:col-start-3 lg:col-end-4 lg:row-start-1'>
<RelatedGuides <RelatedGuides
relatedTitle={guideFrontmatter?.relatedTitle} relatedTitle={guideFrontmatter?.relatedTitle}
relatedGuides={guideFrontmatter?.relatedGuides || {}} relatedGuides={questionGroup?.relatedGuides || {}}
client:load client:load
/> />
<TableOfContent toc={tableOfContent} client:load /> <TableOfContent toc={tableOfContent} client:load />
@ -86,7 +80,7 @@ const { frontmatter: guideFrontmatter, author } = questionGroup;
> >
<MarkdownFile> <MarkdownFile>
<h1 class='mb-3 text-balance text-4xl font-bold'> <h1 class='mb-3 text-balance text-4xl font-bold'>
{replaceVariables(guideFrontmatter.title)} {guideFrontmatter.title}
</h1> </h1>
{ {
author && ( author && (
@ -142,8 +136,8 @@ const { frontmatter: guideFrontmatter, author } = questionGroup;
</h3> </h3>
{questionGroup.questions {questionGroup.questions
.filter((q) => { .filter((q) => {
return q.topics return q?.topics
.map((t) => t.toLowerCase()) ?.map((t) => t.toLowerCase())
.includes(questionLevel); .includes(questionLevel);
}) })
.map((q) => ( .map((q) => (

@ -8,14 +8,7 @@ seo:
description: 'Learn what the essential backend developer skills are that you should learn and master to advance in your career.' description: 'Learn what the essential backend developer skills are that you should learn and master to advance in your career.'
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-developer-skills-ece68.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/backend-developer-skills-ece68.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-02-27 date: 2024-02-27

@ -8,14 +8,7 @@ seo:
description: 'Elevate your coding with backend developer tools that bring efficiency, scalability, and innovation to your projects. Improve your development process today!' description: 'Elevate your coding with backend developer tools that bring efficiency, scalability, and innovation to your projects. Improve your development process today!'
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-development-tools-ou6el.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/backend-development-tools-ou6el.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-03-19 date: 2024-03-19

@ -8,14 +8,7 @@ seo:
description: 'Get expert advice on backend frameworks for 2024. Learn about the top 7 frameworks that can elevate your development process.' description: 'Get expert advice on backend frameworks for 2024. Learn about the top 7 frameworks that can elevate your development process.'
ogImageUrl: 'https://assets.roadmap.sh/guest/top-backend-frameworks-jfpux.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/top-backend-frameworks-jfpux.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-09-27 date: 2024-09-27

@ -1,21 +1,14 @@
--- ---
title: "Backend Developer Job Description [2024 Template]" title: "Backend Developer Job Description [@currentYear@ Template]"
description: 'Learn how to write the perfect backend developer job description and get my best tips on how to recruit backend dev talent effectively.' description: 'Learn how to write the perfect backend developer job description and get my best tips on how to recruit backend dev talent effectively.'
authorId: ekene authorId: ekene
excludedBySlug: '/backend/job-description' excludedBySlug: '/backend/job-description'
seo: seo:
title: "Backend Developer Job Description [2024 Template]" title: "Backend Developer Job Description [@currentYear@ Template]"
description: '' description: ''
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-job-description-nn3ja.png' ogImageUrl: 'https://assets.roadmap.sh/guest/backend-job-description-nn3ja.png'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
isNew: true isNew: true
type: 'textual' type: 'textual'
date: 2024-11-12 date: 2024-11-12

@ -8,14 +8,7 @@ seo:
description: 'Discover the best backend development languages to learn right now for career development, with practical tips from an experienced developer.' description: 'Discover the best backend development languages to learn right now for career development, with practical tips from an experienced developer.'
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-languages-2x930.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/backend-languages-2x930.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-01-18 date: 2024-01-18

@ -8,14 +8,7 @@ seo:
description: 'Seeking backend projects to enhance your skills? Explore our top 20 project ideas, from simple apps to complex systems. Start building today!' description: 'Seeking backend projects to enhance your skills? Explore our top 20 project ideas, from simple apps to complex systems. Start building today!'
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-project-ideas-zxutw.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/backend-project-ideas-zxutw.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-05-09 date: 2024-05-09

@ -8,14 +8,7 @@ seo:
description: 'Looking for the best backend technologies in @currentYear@? Check out our expert list of top tools for developers.' description: 'Looking for the best backend technologies in @currentYear@? Check out our expert list of top tools for developers.'
ogImageUrl: 'https://assets.roadmap.sh/guest/backend-technologies-pnof4.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/backend-technologies-pnof4.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: backend
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"50 Popular Backend Developer Interview Questions and Answers": "/questions/backend"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-08-27 date: 2024-08-27

@ -8,15 +8,7 @@ seo:
description: 'Explore the best DevOps automation tools designed to optimize CI/CD, reduce manual tasks, and drive efficiency in your development cycle.' description: 'Explore the best DevOps automation tools designed to optimize CI/CD, reduce manual tasks, and drive efficiency in your development cycle.'
ogImageUrl: 'https://assets.roadmap.sh/guest/best-devops-automation-tools-aoyls.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/best-devops-automation-tools-aoyls.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: true isNew: true
type: 'textual' type: 'textual'
date: 2024-11-26 date: 2024-11-26

@ -8,14 +8,7 @@ seo:
description: 'Streamline your DevOps pipeline! Explore what DevOps automation is and the 8 best practices for seamless delivery.' description: 'Streamline your DevOps pipeline! Explore what DevOps automation is and the 8 best practices for seamless delivery.'
ogImageUrl: 'https://assets.roadmap.sh/guest/what-is-devops-automation-03k11.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/what-is-devops-automation-03k11.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
isNew: true isNew: true
type: 'textual' type: 'textual'
date: 2024-11-05 date: 2024-11-05

@ -8,14 +8,7 @@ seo:
description: 'Learn DevOps best practices for building efficient workflows, from code integration to monitoring, and avoid common DevOps anti-patterns.' description: 'Learn DevOps best practices for building efficient workflows, from code integration to monitoring, and avoid common DevOps anti-patterns.'
ogImageUrl: 'https://assets.roadmap.sh/guest/devops-best-practices-4yhmb.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/devops-best-practices-4yhmb.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
isNew: true isNew: true
type: 'textual' type: 'textual'
date: 2024-11-26 date: 2024-11-26

@ -8,14 +8,7 @@ seo:
description: 'Learn why a DevOps career path is a smart choice in 2024. Get insights into demand, growth, and earning potential in DevOps.' description: 'Learn why a DevOps career path is a smart choice in 2024. Get insights into demand, growth, and earning potential in DevOps.'
ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-career-path-2h4r7.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-career-path-2h4r7.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-08-20 date: 2024-08-20

@ -8,14 +8,7 @@ seo:
description: 'Master the DevOps lifecycle by exploring its 7 phases, designed to enhance collaboration, streamline processes, and deliver software with agility.' description: 'Master the DevOps lifecycle by exploring its 7 phases, designed to enhance collaboration, streamline processes, and deliver software with agility.'
ogImageUrl: 'https://assets.roadmap.sh/guest/key-phases-of-devops-lifecycle-788fa.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/key-phases-of-devops-lifecycle-788fa.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-11-01 date: 2024-11-01

@ -8,14 +8,7 @@ seo:
description: 'Elevate your game by understanding this set of key DevOps principles and practices. Gain pro insights for a more efficient, collaborative workflow!' description: 'Elevate your game by understanding this set of key DevOps principles and practices. Gain pro insights for a more efficient, collaborative workflow!'
ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-skills-tlace.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-skills-tlace.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-09-24 date: 2024-09-24

@ -8,14 +8,7 @@ seo:
description: 'Understand why DevOps emphasizes shift-left testing to boost early bug detection, reduce costs, and improve release cycles.' description: 'Understand why DevOps emphasizes shift-left testing to boost early bug detection, reduce costs, and improve release cycles.'
ogImageUrl: 'https://assets.roadmap.sh/guest/devops-shift-left-testing-16zah.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/devops-shift-left-testing-16zah.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: true isNew: true
type: 'textual' type: 'textual'
date: 2024-11-04 date: 2024-11-04

@ -8,14 +8,7 @@ seo:
description: 'Find out exactly what it takes to be a successful DevOps engineer with my recommendations for essential DevOps skills' description: 'Find out exactly what it takes to be a successful DevOps engineer with my recommendations for essential DevOps skills'
ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-skills-tlace.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-skills-tlace.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-09-12 date: 2024-09-12

@ -8,14 +8,7 @@ seo:
description: 'DevOps engineer vs Full stack developer: Compare the roles, required skills, and future prospects to make an informed career choice.' description: 'DevOps engineer vs Full stack developer: Compare the roles, required skills, and future prospects to make an informed career choice.'
ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-vs-full-stack-developer-jccsq.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/devops-engineer-vs-full-stack-developer-jccsq.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'How to become a DevOps Engineer in 2024': '/devops/how-to-become-devops-engineer'
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-10-17 date: 2024-10-17

@ -8,14 +8,7 @@ seo:
description: 'Master these 12 in-demand front end developer skills and become a standout candidate in the web development field.' description: 'Master these 12 in-demand front end developer skills and become a standout candidate in the web development field.'
ogImageUrl: 'https://assets.roadmap.sh/guest/frontend-developer-skills-zdpyd.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/frontend-developer-skills-zdpyd.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-07-04 date: 2024-07-04

@ -8,14 +8,7 @@ seo:
description: 'Get expert advice on frontend frameworks for 2024. Elevate your web development process with these top picks.' description: 'Get expert advice on frontend frameworks for 2024. Elevate your web development process with these top picks.'
ogImageUrl: 'https://assets.roadmap.sh/guest/top-frontend-frameworks-wmqwc.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/top-frontend-frameworks-wmqwc.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-09-26 date: 2024-09-26

@ -1,21 +1,14 @@
--- ---
title: "Frontend Developer Job Description [2024 Template]" title: "Frontend Developer Job Description [@currentYear@ Template]"
description: 'Learn how to write the perfect frontend developer job description and get my best tips on how to recruit frontend dev talent effectively.' description: 'Learn how to write the perfect frontend developer job description and get my best tips on how to recruit frontend dev talent effectively.'
authorId: william authorId: william
excludedBySlug: '/frontend/job-description' excludedBySlug: '/frontend/job-description'
seo: seo:
title: "Frontend Developer Job Description [2024 Template]" title: "Frontend Developer Job Description [@currentYear@ Template]"
description: 'Learn how to write the perfect frontend developer job description and get my best tips on how to recruit frontend dev talent effectively.' description: 'Learn how to write the perfect frontend developer job description and get my best tips on how to recruit frontend dev talent effectively.'
ogImageUrl: 'https://assets.roadmap.sh/guest/frontend-developer-job-description-5fwzy.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/frontend-developer-job-description-5fwzy.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
isNew: true isNew: true
type: 'textual' type: 'textual'
date: 2024-11-04 date: 2024-11-04

@ -8,14 +8,7 @@ seo:
description: 'Get ahead in web development. Discover the essential frontend languages every pro developer uses!' description: 'Get ahead in web development. Discover the essential frontend languages every pro developer uses!'
ogImageUrl: 'https://assets.roadmap.sh/guest/best-front-end-languages-gzngm.png' ogImageUrl: 'https://assets.roadmap.sh/guest/best-front-end-languages-gzngm.png'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-05-02 date: 2024-05-02

@ -8,14 +8,7 @@ seo:
description: 'Learn the key differences between frontend and backend in AI development, from roles to tools, and how they impact project success.' description: 'Learn the key differences between frontend and backend in AI development, from roles to tools, and how they impact project success.'
ogImageUrl: 'https://assets.roadmap.sh/guest/frontend-vs-backend-in-ai-43wtm.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/frontend-vs-backend-in-ai-43wtm.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-10-17 date: 2024-10-17

@ -8,14 +8,7 @@ seo:
description: 'Build an impressive online presence with these 10 handpicked web developer portfolio templates.' description: 'Build an impressive online presence with these 10 handpicked web developer portfolio templates.'
ogImageUrl: 'https://assets.roadmap.sh/guest/roammap-18-xvyn0.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/roammap-18-xvyn0.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-10-18 date: 2024-10-18

@ -1,10 +1,10 @@
--- ---
title: 'Full Stack Developer Job Description [2024 Template]' title: 'Full Stack Developer Job Description [@currentYear@ Template]'
description: 'Looking to hire a Fullstack Engineer? Get the complete job description, skills, and responsibilities right here!' description: 'Looking to hire a Fullstack Engineer? Get the complete job description, skills, and responsibilities right here!'
authorId: william authorId: william
excludedBySlug: '/full-stack/job-description' excludedBySlug: '/full-stack/job-description'
seo: seo:
title: 'Full Stack Developer Job Description [2024 Template]' title: 'Full Stack Developer Job Description [@currentYear@ Template]'
description: 'Looking to hire a Fullstack Engineer? Get the complete job description, skills, and responsibilities right here!' description: 'Looking to hire a Fullstack Engineer? Get the complete job description, skills, and responsibilities right here!'
ogImageUrl: 'https://assets.roadmap.sh/guest/fullstack-job-h15x6.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/fullstack-job-h15x6.jpg'
isNew: false isNew: false

@ -8,14 +8,7 @@ seo:
description: 'Want to become a DevOps engineer? Our @currentYear@ guide covers skills, certifications, and expert career advice. Start your journey today!' description: 'Want to become a DevOps engineer? Our @currentYear@ guide covers skills, certifications, and expert career advice. Start your journey today!'
ogImageUrl: 'https://assets.roadmap.sh/guest/become-devops-engineer-4x2p7.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/become-devops-engineer-4x2p7.jpg'
relatedGuidesTitle: 'Other Guides' relatedGuidesTitle: 'Other Guides'
relatedGuides: relatedGuidesId: devops
'Is DevOps engineering a good career path in 2024?': '/devops/career-path'
'10+ In-Demand DevOps Engineer Skills to Master': '/devops/skills'
'DevOps engineer vs Full stack developer: Which is best?': '/devops/vs-full-stack'
'11 DevOps Principles and Practices to Master: Pro Advice': '/devops/principles'
'What Are the 7 Key Phases of the DevOps Lifecycle?': '/devops/lifecycle'
'Why Does DevOps Recommend Shift-Left Testing Principles?': '/devops/shift-left-testing'
'What is DevOps Automation? 8 Best Practices & Advice': '/devops/automation'
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-06-11 date: 2024-06-11

@ -8,14 +8,7 @@ seo:
description: 'Learn how to become a front-end developer in 7 clear steps. Start your coding journey with practical tips and resources today!' description: 'Learn how to become a front-end developer in 7 clear steps. Start your coding journey with practical tips and resources today!'
ogImageUrl: 'https://assets.roadmap.sh/guest/how-to-become-frontend-developer-i23nx.jpg' ogImageUrl: 'https://assets.roadmap.sh/guest/how-to-become-frontend-developer-i23nx.jpg'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: frontend
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 30 Popular Front End Developer Interview Questions": "/questions/frontend"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
isNew: false isNew: false
type: 'textual' type: 'textual'
date: 2024-08-15 date: 2024-08-15

@ -17,14 +17,7 @@ seo:
- 'backend interview' - 'backend interview'
- 'backend test' - 'backend test'
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: "backend"
"The 5 Best Backend Development Languages to Master (2024)": "/backend/languages"
"Top 10+ Backend Technologies to Use in 2024: Expert Advice": "/backend/technologies"
"Top 7 Backend Frameworks to Use in 2024: Pro Advice": "/backend/frameworks"
"8 In-Demand Backend Developer Skills to Master": "/backend/developer-skills"
"25 Essential Backend Development Tools for 2024": "/backend/developer-tools"
"20 Backend Project Ideas to take you from Beginner to Pro": "/backend/project-ideas"
"Backend Developer Job Description [2024 Template]": "/backend/job-description"
sitemap: sitemap:
priority: 1 priority: 1
changefreq: 'monthly' changefreq: 'monthly'

@ -8,14 +8,7 @@ authorId: 'fernando'
isNew: false isNew: false
date: 2024-05-24 date: 2024-05-24
relatedTitle: "Other Guides" relatedTitle: "Other Guides"
relatedGuides: relatedGuidesId: 'frontend'
"How to Become a Front-End Developer in 7 Steps": "/frontend/how-to-become-frontend-developer"
"What Front End Programming Languages Should You Learn?": "/frontend/languages"
"Top 7 Frontend Frameworks to Use in 2024: Pro Advice": "/frontend/frameworks"
"12 In-Demand Front End Developer Skills to Master": "/frontend/developer-skills"
"Top 10 Web Developer Portfolio Templates - A Pro’s Pick": "/frontend/web-developer-portfolio"
"Frontend vs. Backend in AI Development": "/frontend/vs-backend-ai"
"Frontend Developer Job Description [2024 Template]": "/frontend/job-description"
seo: seo:
title: 'Top 30 Popular Front End Developer Interview Questions' title: 'Top 30 Popular Front End Developer Interview Questions'
description: 'Nail your frontend developer interview with these 30 popularly asked questions and answers. Test your knowledge with our quiz cards!' description: 'Nail your frontend developer interview with these 30 popularly asked questions and answers. Test your knowledge with our quiz cards!'

@ -1,5 +1,6 @@
import type { MarkdownFileType } from './file'; import type { MarkdownFileType } from './file';
import { type AuthorFileType, getAllAuthors } from './author.ts'; import { type AuthorFileType, getAllAuthors } from './author.ts';
import { replaceVariables } from './markdown.ts';
export interface GuideFrontmatter { export interface GuideFrontmatter {
title: string; title: string;
@ -21,13 +22,14 @@ export interface GuideFrontmatter {
changefreq: 'daily' | 'weekly' | 'monthly' | 'yearly'; changefreq: 'daily' | 'weekly' | 'monthly' | 'yearly';
}; };
relatedTitle?: string; relatedTitle?: string;
relatedGuides?: Record<string, string>; relatedGuidesId?: string;
tags: string[]; tags: string[];
} }
export type GuideFileType = MarkdownFileType<GuideFrontmatter> & { export type GuideFileType = MarkdownFileType<GuideFrontmatter> & {
id: string; id: string;
author: AuthorFileType; author: AuthorFileType;
relatedGuides?: Record<string, string>;
}; };
/** /**
@ -63,13 +65,44 @@ export async function getAllGuides(): Promise<GuideFileType[]> {
const allAuthors = await getAllAuthors(); const allAuthors = await getAllAuthors();
const guideFiles = Object.values(guides) as GuideFileType[]; const guideFiles = Object.values(guides) as GuideFileType[];
const enrichedGuides: GuideFileType[] = guideFiles.map((guideFile) => ({
...guideFile, let enrichedGuides: GuideFileType[] = guideFiles.map((guideFile) => {
id: guidePathToId(guideFile.file), let relatedGuides: GuideFileType[] = [];
author: allAuthors.find( if (guideFile.frontmatter.relatedGuidesId) {
(author) => author.id === guideFile.frontmatter.authorId, relatedGuides = guideFiles.filter(
)!, (g) =>
})); g?.frontmatter?.relatedGuidesId ===
guideFile.frontmatter.relatedGuidesId && g.file !== guideFile.file,
);
}
return {
...guideFile,
id: guidePathToId(guideFile.file),
author: allAuthors.find(
(author) => author.id === guideFile.frontmatter.authorId,
)!,
frontmatter: {
...guideFile.frontmatter,
title: replaceVariables(guideFile.frontmatter.title),
description: replaceVariables(guideFile.frontmatter.description),
seo: {
...(guideFile.frontmatter?.seo || {}),
title: replaceVariables(guideFile.frontmatter.seo.title),
description: replaceVariables(guideFile.frontmatter.seo.description),
},
},
relatedGuides: relatedGuides.reduce(
(acc, guide) => {
acc[replaceVariables(guide.frontmatter.title)] =
guide.frontmatter?.excludedBySlug ||
`/guides/${guidePathToId(guideFile.file)}`;
return acc;
},
{} as Record<string, string>,
),
};
});
return enrichedGuides.sort( return enrichedGuides.sort(
(a, b) => (a, b) =>

@ -1,6 +1,7 @@
import type { MarkdownFileType } from './file'; import type { MarkdownFileType } from './file';
import slugify from 'slugify'; import slugify from 'slugify';
import { getAllAuthors } from './author.ts'; import { getAllAuthors, type AuthorFileType } from './author.ts';
import { getAllGuides } from './guide.ts';
interface RawQuestionGroupFrontmatter { interface RawQuestionGroupFrontmatter {
order: number; order: number;
@ -18,7 +19,7 @@ interface RawQuestionGroupFrontmatter {
keywords: string[]; keywords: string[];
}; };
relatedTitle?: string; relatedTitle?: string;
relatedGuides?: Record<string, string>; relatedGuidesId?: string;
sitemap: { sitemap: {
priority: number; priority: number;
changefreq: string; changefreq: string;
@ -46,6 +47,8 @@ export type QuestionType = {
export type QuestionGroupType = RawQuestionGroupFileType & { export type QuestionGroupType = RawQuestionGroupFileType & {
questions: QuestionType[]; questions: QuestionType[];
allTopics: string[]; allTopics: string[];
author?: AuthorFileType;
relatedGuides?: Record<string, string>;
}; };
/** /**
@ -71,6 +74,7 @@ export async function getAllQuestionGroups(): Promise<QuestionGroupType[]> {
); );
const allAuthors = await getAllAuthors(); const allAuthors = await getAllAuthors();
const allGuides = await getAllGuides();
return Object.values(questionGroupFilesMap) return Object.values(questionGroupFilesMap)
.map((questionGroupFile) => { .map((questionGroupFile) => {
@ -114,6 +118,21 @@ export async function getAllQuestionGroups(): Promise<QuestionGroupType[]> {
return acc; return acc;
}, [] as string[]); }, [] as string[]);
const relatedGuides = questionGroupFile.frontmatter.relatedGuidesId
? allGuides
.filter(
(guide) =>
guide.id === questionGroupFile.frontmatter.relatedGuidesId,
)
.reduce(
(acc, guide) => {
acc[guide.frontmatter.title] = `/guides/${guide.id}`;
return acc;
},
{} as Record<string, string>,
)
: undefined;
return { return {
...questionGroupFile, ...questionGroupFile,
id: questionGroupFileId, id: questionGroupFileId,
@ -122,6 +141,7 @@ export async function getAllQuestionGroups(): Promise<QuestionGroupType[]> {
author: allAuthors.find( author: allAuthors.find(
(author) => author.id === questionGroupFile.frontmatter.authorId, (author) => author.id === questionGroupFile.frontmatter.authorId,
)!, )!,
relatedGuides,
}; };
}) })
.sort((a, b) => a.frontmatter.order - b.frontmatter.order); .sort((a, b) => a.frontmatter.order - b.frontmatter.order);

@ -1,10 +1,8 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown';
const guideId = 'backend-developer-skills'; const guideId = 'backend-developer-skills';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,13 +18,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={`/backend/developer-skills`} permalink={`/backend/developer-skills`}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot='changelog-banner'></div>
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={`/backend/developer-tools`} permalink={`/backend/developer-tools`}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -23,13 +22,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={`/backend/frameworks`} permalink={`/backend/frameworks`}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -26,6 +25,5 @@ const ogImageUrl =
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -23,13 +22,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={`/backend/languages`} permalink={`/backend/languages`}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={`/backend/project-ideas`} permalink={`/backend/project-ideas`}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -23,13 +22,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guide.frontmatter.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guide.frontmatter.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guide.frontmatter.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guide.frontmatter.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guide.frontmatter.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guide.frontmatter.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,10 +1,9 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown'; import { replaceVariables } from '../../lib/markdown';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
const guideId = 'how-to-become-devops-engineer'; const guideId = 'how-to-become-devops-engineer';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,10 +1,9 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown'; import { replaceVariables } from '../../lib/markdown';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
const guideId = 'devops-skills'; const guideId = 'devops-skills';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,10 +1,9 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown'; import { replaceVariables } from '../../lib/markdown';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
const guideId = 'devops-vs-full-stack'; const guideId = 'devops-vs-full-stack';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,13 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,10 +1,9 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown'; import { replaceVariables } from '../../lib/markdown';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
const guideId = 'frontend-developer-skills'; const guideId = 'frontend-developer-skills';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,10 +1,9 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown'; import { replaceVariables } from '../../lib/markdown';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
const guideId = 'frontend-frameworks'; const guideId = 'frontend-frameworks';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -26,6 +25,6 @@ const ogImageUrl =
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,10 +1,9 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown'; import { replaceVariables } from '../../lib/markdown';
import { getOpenGraphImageUrl } from '../../lib/open-graph';
const guideId = 'frontend-languages'; const guideId = 'frontend-languages';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -20,12 +19,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

@ -1,6 +1,5 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getAllGuides, type GuideFileType } from '../../lib/guide'; import { getAllGuides, type GuideFileType } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
@ -34,13 +33,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={`/guides/${guideId}`} permalink={`/guides/${guideId}`}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" /> <div slot="changelog-banner" />

@ -1,10 +1,8 @@
--- ---
import GuideContent from '../../components/Guide/GuideContent.astro'; import GuideContent from '../../components/Guide/GuideContent.astro';
import GuideHeader from '../../components/GuideHeader.astro';
import BaseLayout from '../../layouts/BaseLayout.astro'; import BaseLayout from '../../layouts/BaseLayout.astro';
import { getGuideById } from '../../lib/guide'; import { getGuideById } from '../../lib/guide';
import { getOpenGraphImageUrl } from '../../lib/open-graph'; import { getOpenGraphImageUrl } from '../../lib/open-graph';
import { replaceVariables } from '../../lib/markdown';
const guideId = 'java-developer-skills'; const guideId = 'java-developer-skills';
const guide = await getGuideById(guideId); const guide = await getGuideById(guideId);
@ -20,12 +18,12 @@ const ogImageUrl =
--- ---
<BaseLayout <BaseLayout
title={replaceVariables(guideData.seo.title)} title={guideData.seo.title}
description={replaceVariables(guideData.seo.description)} description={guideData.seo.description}
permalink={guide.frontmatter.excludedBySlug} permalink={guideData.excludedBySlug}
canonicalUrl={guideData.canonicalUrl} canonicalUrl={guideData.canonicalUrl}
ogImageUrl={ogImageUrl} ogImageUrl={ogImageUrl}
> >
<GuideHeader guide={guide!} />
<GuideContent guide={guide!} /> <GuideContent guide={guide!} />
<div slot="changelog-banner" />
</BaseLayout> </BaseLayout>

Loading…
Cancel
Save