# How Role, Skill, and Best-Practice Roadmap Types Are Handled Distinctly in Developer Roadmap

> Discover how the developer roadmap repository distinctly handles role, skill, and best-practice roadmap types. Learn about separate definitions, data fetching, routing, and metadata.

- Repository: [Kamran Ahmed/developer-roadmap](https://github.com/kamranahmedse/developer-roadmap)
- Tags: deep-dive
- Published: 2026-02-24

---

**The repository treats role, skill, and best-practice as separate architectural categories through distinct type definitions in [`src/queries/official-roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/official-roadmap.ts), separate data fetching mechanisms (API endpoints versus static Markdown globbing), unique URL routing patterns, and differentiated metadata tagging during site generation.**

The developer-roadmap repository organizes learning paths into three distinct roadmap types: role-based career tracks, skill-specific technologies, and best-practice guidelines. Understanding how these different roadmap types are handled distinctly requires examining the type definitions, data layer implementations, and routing architectures that separate role and skill roadmaps from best-practice content.

## Type Definitions and Allowed Categories

The codebase enforces strict type safety across the three roadmap variants through a centralized type definition system.

### Role and Skill Enumeration

In [`src/queries/official-roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/official-roadmap.ts), the allowed categories are declared as a const assertion that forms the basis of the type system:

```typescript
export const allowedOfficialRoadmapType = ['skill', 'role', 'best-practice'] as const;
export type AllowedOfficialRoadmapType = (typeof allowedOfficialRoadmapType)[number];

```

This **AllowedOfficialRoadmapType** union ensures that only valid roadmap types propagate through the application's data layer.

### Best-Practice Data Model

Unlike role and skill types, best-practice roadmaps are managed by a dedicated module in [`src/lib/best-practice.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/best-practice.ts). This module handles Markdown file discovery and content loading rather than API endpoint consumption, establishing a separate architectural path for this roadmap type.

## Data Fetching Architectures

The repository implements two fundamentally different data retrieval strategies based on roadmap classification.

### API-Based Retrieval for Role and Skill Roadmaps

Role and skill roadmaps are fetched via the **official-roadmap API** endpoint (`/v1-official-roadmap/:slug`). The response includes a `type` field that distinguishes between career roles (e.g., "frontend-developer") and specific skills (e.g., "react").

```typescript
import { officialRoadmapDetails } from '$src/queries/official-roadmap';

const roleRoadmap = await officialRoadmapDetails('frontend-developer');
if (roleRoadmap?.type === 'role') {
  console.log('This is a role roadmap for a Front-End Developer');
}

```

For skill-specific roadmaps, the same function returns a type of `'skill'`:

```typescript
import { officialRoadmapDetails } from '$src/queries/official-roadmap';

const skillRoadmap = await officialRoadmapDetails('react');
if (skillRoadmap?.type === 'skill') {
  console.log('Skill roadmap for React');
}

```

### Static File Loading for Best-Practice Content

Best-practice roadmaps bypass the API entirely. The system uses Vite's `import.meta.glob` to dynamically load static Markdown files from the filesystem:

```typescript
import { getBestPracticeById } from '$src/lib/best-practice';

const bp = await getBestPracticeById('frontend-performance/use-https-everywhere');
console.log(bp.frontmatter.title); // "Use HTTPS Everywhere"

```

This approach allows best-practices to be maintained as documentation-like content in `src/data/best-practices/*/*.md`, loaded via the `getAllBestPractices` and `getBestPracticeById` helpers.

## Routing and URL Structure

The URL architecture reinforces the semantic differences between roadmap types. Role and skill roadmaps share the dynamic route pattern `/[roadmapSlug]`, with beginner variants expressed through query parameters (`?r=…`). Best-practice content lives under the dedicated `/best-practices/:id` namespace, as defined in [`src/lib/best-practice.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/best-practice.ts).

## Metadata Tagging and Site Generation

During the build process, [`src/pages/pages.json.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/pages/pages.json.ts) assigns distinct metadata tags based on the roadmap type. Role roadmaps receive `['role-roadmap']` tags, while skill roadmaps receive `['skill-roadmap']`. Best-practice pages receive a static `group: 'Best Practices'` entry and never receive the role/skill classification tags.

```typescript
import { listOfficialRoadmaps } from '$src/queries/official-roadmap';

const roadmaps = await listOfficialRoadmaps();
const roleMeta = roadmaps
  .filter(r => r.type === 'role')
  .map(r => ({
    url: `/${r.slug}`,
    tags: ['role-roadmap'],
  }));

```

## Resource Type Discrimination

The `getResourceMeta` helper in [`src/lib/roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/roadmap.ts) performs top-level discrimination using the **ResourceType** union (defined in [`src/lib/resource-progress.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/resource-progress.ts) as `'roadmap' | 'best-practice'`). When processing roadmaps, the helper further inspects the `type` field to distinguish role from skill variants. Best-practice resources are identified by their `/best-practices/` URL prefix:

```typescript
if (resourceType === 'roadmap') {
  return page.url === `/${resourceId}`;
} else if (resourceType === 'best-practice') {
  return page.url === `/best-practices/${resourceId}`;
}

```

## Summary

- **Type Safety**: The `AllowedOfficialRoadmapType` union in [`src/queries/official-roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/official-roadmap.ts) enforces strict typing across role, skill, and best-practice categories.
- **Data Layer Separation**: Role and skill roadmaps use the official API endpoint, while best-practices use static Markdown globbing via `import.meta.glob` in [`src/lib/best-practice.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/best-practice.ts).
- **URL Architecture**: Role and skill roadmaps share `/{slug}` routes; best-practices use the dedicated `/best-practices/{id}` path.
- **Metadata Differentiation**: Site generation applies `role-roadmap` or `skill-roadmap` tags to official roadmaps, while best-practices receive static group assignments in the site map.
- **Resource Helpers**: The `getResourceMeta` function in [`src/lib/roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/roadmap.ts) routes logic based on `resourceType` and URL patterns, with special handling for best-practice identification.

## Frequently Asked Questions

### What distinguishes a role roadmap from a skill roadmap in the codebase?

While both use the same API infrastructure in [`src/queries/official-roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/official-roadmap.ts) and share routing patterns, the `type` field in the roadmap document differentiates them. Role roadmaps represent career paths (e.g., "DevOps Engineer"), while skill roadmaps cover specific technologies (e.g., "Docker"). During site generation in [`src/pages/pages.json.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/pages/pages.json.ts), roles receive `['role-roadmap']` metadata tags, and skills receive `['skill-roadmap']` tags, enabling filtered views and categorization.

### Why are best-practice roadmaps handled separately from role and skill types?

Best-practice content resides in static Markdown files within `src/data/best-practices/` rather than the database-driven API used for official roadmaps. This architectural decision allows best-practices to be maintained as documentation-like content, loaded via Vite's `import.meta.glob` helpers in [`src/lib/best-practice.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/best-practice.ts), and served under the `/best-practices/` URL namespace, completely separate from the dynamic roadmap routing system.

### How does the application determine which type of roadmap to render?

The `getResourceMeta` helper in [`src/lib/roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/roadmap.ts) checks the `resourceType` parameter against the **ResourceType** union (`'roadmap' | 'best-practice'`). For roadmaps, it matches URLs against `/${resourceId}`, while best-practices match against `/best-practices/${resourceId}`. When processing roadmaps, the system further inspects the `type` property (role vs. skill) to determine specific rendering metadata and page classifications.

### Can the roadmap type be changed dynamically after creation?

The roadmap type is defined at the data level in the source files. For role and skill roadmaps, the `type` field is set in the backend API data consumed by [`src/queries/official-roadmap.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/queries/official-roadmap.ts). For best-practices, the type is implicit in the file location and loading mechanism in [`src/lib/best-practice.ts`](https://github.com/kamranahmedse/developer-roadmap/blob/main/src/lib/best-practice.ts). Changing a roadmap's classification requires updating these source definitions, as the frontend relies on these distinctions for routing logic, metadata generation, and resource progress tracking.