diff --git a/scripts/generate-og-images.mjs b/scripts/generate-og-images.mjs
index 7cbc9ddcd..988d8a57c 100644
--- a/scripts/generate-og-images.mjs
+++ b/scripts/generate-og-images.mjs
@@ -6,6 +6,7 @@ import satori from 'satori';
import sharp from 'sharp';
import imageSize from 'image-size';
import { Resvg } from '@resvg/resvg-js';
+import { getRepositoryRank } from '../src/lib/github';
const ALL_ROADMAP_DIR = path.join(process.cwd(), '/src/data/roadmaps');
const ALL_BEST_PRACTICE_DIR = path.join(
@@ -28,6 +29,11 @@ const alreadyGeneratedImages = await fs.readdir(
},
);
+async function updateRank() {
+ const repoRank = await getRepositoryRank('kamranahmedse/developer-roadmap');
+ document.getElementById('repo-rank').innerText = `${repoRank} most starred GitHub project`;
+}
+
async function getAllRoadmaps() {
const allRoadmapDirNames = await fs.readdir(ALL_ROADMAP_DIR);
@@ -142,6 +148,8 @@ async function getAllBestPracticeImageIds() {
}
async function generateResourceOpenGraph() {
+ await updateRank();
+
const allRoadmaps = (await getAllRoadmaps()).filter(
(roadmap) => !alreadyGeneratedImages.includes(`roadmaps/${roadmap.id}.png`),
);
@@ -371,8 +379,8 @@ function getRoadmapDefaultTemplate({ title, description }) {
/>
-
- 6th most starred GitHub project
+
+ Loading...
diff --git a/src/components/OpenSourceBanner.astro b/src/components/OpenSourceBanner.astro
index b04427c88..42905aec0 100644
--- a/src/components/OpenSourceBanner.astro
+++ b/src/components/OpenSourceBanner.astro
@@ -1,10 +1,12 @@
---
-import { getFormattedStars } from '../lib/github';
+import { getFormattedStars, getRepositoryRank } from '../lib/github';
import Icon from './AstroIcon.astro';
import { getDiscordInfo } from '../lib/discord';
import OpenSourceStat from './OpenSourceStat.astro';
-const starCount = await getFormattedStars('kamranahmedse/developer-roadmap');
+const repoName = 'kamranahmedse/developer-roadmap';
+const starCount = await getFormattedStars(repoName);
+const repoRank = await getRepositoryRank(repoName);
const discordInfo = await getDiscordInfo();
---
@@ -16,7 +18,7 @@ const discordInfo = await getDiscordInfo();
href='https://github.com/search?o=desc&q=stars%3A%3E100000&s=stars&type=Repositories'
target='_blank'
class='font-medium text-gray-600 underline underline-offset-2 hover:text-black'
- >6th most starred project on GitHub{repoRank} most starred project on GitHub and is visited by hundreds of thousands of developers every month.
diff --git a/src/components/OpenSourceStat.astro b/src/components/OpenSourceStat.astro
index 54d9ca814..36dee7ac9 100644
--- a/src/components/OpenSourceStat.astro
+++ b/src/components/OpenSourceStat.astro
@@ -1,6 +1,7 @@
---
import { ChevronUp } from 'lucide-react';
import Icon from './AstroIcon.astro';
+import { getRepositoryRank } from '../lib/github';
export interface Props {
value: string;
text: string;
@@ -11,6 +12,8 @@ const { value, text } = Astro.props;
const isGitHubStars = text.toLowerCase() === 'github stars';
const isRegistered = text.toLowerCase() === 'registered users';
const isDiscordMembers = text.toLowerCase() === 'discord members';
+
+const repoRank = await getRepositoryRank('kamranahmedse/developer-roadmap');
---
- Rank 6th
+ Rank {repoRank}
out of 28M!
)
diff --git a/src/lib/github.ts b/src/lib/github.ts
index 26e7988a8..ffe36c467 100644
--- a/src/lib/github.ts
+++ b/src/lib/github.ts
@@ -32,3 +32,42 @@ export async function getFormattedStars(
return formatter.format(stars);
}
+
+const defaultRanking = "7th";
+let ranking: string;
+
+export async function getRepositoryRank(
+ repo = 'kamranahmedse/developer-roadmap',
+): Promise {
+ try {
+ const response = await fetch(`https://api.github.com/search/repositories?q=stars:>100000&o=desc&s=stars`);
+ const json = await response.json();
+ const repositories = json.items || [];
+ for (let rank = 1; rank <= repositories.length; rank++) {
+ if (repositories[rank - 1].full_name.toLowerCase() === repo.toLowerCase()) {
+ ranking = `${rank}${getOrdinalSuffix(rank)}`;
+ }
+ }
+ } catch (e) {
+ console.log('Failed to fetch ranking');
+ ranking = defaultRanking;
+ }
+
+ return ranking;
+}
+
+function getOrdinalSuffix(rank: number): string {
+ if (11 <= rank % 100 && rank % 100 <= 13) {
+ return 'th';
+ }
+ switch (rank % 10) {
+ case 1:
+ return 'st';
+ case 2:
+ return 'nd';
+ case 3:
+ return 'rd';
+ default:
+ return 'th';
+ }
+}
\ No newline at end of file
diff --git a/src/pages/about.astro b/src/pages/about.astro
index c78a314ee..1371bb140 100644
--- a/src/pages/about.astro
+++ b/src/pages/about.astro
@@ -1,5 +1,8 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
+import { getRepositoryRank } from '../lib/github.ts';
+
+const repoRank = await getRepositoryRank('kamranahmedse/developer-roadmap');
---
@@ -73,7 +76,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
href='https://github.com/search?o=desc&q=stars%3A%3E100000&s=stars&type=Repositories'
target='_blank'
class='font-bold underline'
- >the 6th most starred opensource project on GitHubthe {repoRank} most starred opensource project on GitHub and gets visited by hundreds of thousands of developers every month.
We also have newsletter with 150,000+ developers. All the roadmaps are
created and reviewed by community and several subject matter experts.