Add author page

pull/5258/head
Kamran Ahmed 9 months ago
parent 37ffc2cc62
commit d958a29862
  1. 125
      pnpm-lock.yaml
  2. 42
      src/components/GuideHeader.astro
  3. 24
      src/components/GuideListItem.astro
  4. 11
      src/data/authors/fernando.md
  5. 13
      src/data/authors/kamran.md
  6. 5
      src/data/guides/asymptotic-notation.md
  7. 5
      src/data/guides/avoid-render-blocking-javascript-with-async-defer.md
  8. 20
      src/data/guides/backend-languages.md
  9. 5
      src/data/guides/basic-authentication.md
  10. 5
      src/data/guides/basics-of-authentication.md
  11. 5
      src/data/guides/big-o-notation.md
  12. 5
      src/data/guides/character-encodings.md
  13. 5
      src/data/guides/ci-cd.md
  14. 5
      src/data/guides/consistency-patterns-in-distributed-systems.md
  15. 5
      src/data/guides/design-patterns-for-humans.md
  16. 5
      src/data/guides/dhcp-in-one-picture.md
  17. 5
      src/data/guides/dns-in-one-picture.md
  18. 5
      src/data/guides/free-resources-to-learn-llms.md
  19. 5
      src/data/guides/history-of-javascript.md
  20. 5
      src/data/guides/how-to-setup-a-jump-server.md
  21. 5
      src/data/guides/http-basic-authentication.md
  22. 5
      src/data/guides/http-caching.md
  23. 5
      src/data/guides/introduction-to-llms.md
  24. 5
      src/data/guides/journey-to-http2.md
  25. 5
      src/data/guides/jwt-authentication.md
  26. 5
      src/data/guides/levels-of-seniority.md
  27. 5
      src/data/guides/oauth.md
  28. 5
      src/data/guides/random-numbers.md
  29. 5
      src/data/guides/scaling-databases.md
  30. 5
      src/data/guides/session-authentication.md
  31. 5
      src/data/guides/session-based-authentication.md
  32. 5
      src/data/guides/setup-and-auto-renew-ssl-certificates.md
  33. 5
      src/data/guides/single-command-database-setup.md
  34. 5
      src/data/guides/ssl-tls-https-ssh.md
  35. 5
      src/data/guides/sso.md
  36. 5
      src/data/guides/token-authentication.md
  37. 5
      src/data/guides/unfamiliar-codebase.md
  38. 5
      src/data/guides/what-are-web-vitals.md
  39. 5
      src/data/guides/what-is-internet.md
  40. 5
      src/data/guides/what-is-sli-slo-sla.md
  41. 1
      src/env.d.ts
  42. 2
      src/icons/github.svg
  43. 1
      src/icons/globe.svg
  44. 10
      src/icons/linkedin-2.svg
  45. 73
      src/lib/author.ts
  46. 32
      src/lib/guide.ts
  47. 14
      src/lib/roadmap.ts
  48. 15
      src/lib/video.ts
  49. 110
      src/pages/authors/[authorId].astro

@ -7,7 +7,7 @@ settings:
dependencies: dependencies:
'@astrojs/react': '@astrojs/react':
specifier: ^3.0.10 specifier: ^3.0.10
version: 3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0)(vite@5.0.12) version: 3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)(vite@5.1.3)
'@astrojs/sitemap': '@astrojs/sitemap':
specifier: ^3.0.5 specifier: ^3.0.5
version: 3.0.5 version: 3.0.5
@ -21,8 +21,8 @@ dependencies:
specifier: ^0.7.1 specifier: ^0.7.1
version: 0.7.1(nanostores@0.9.5)(react@18.2.0) version: 0.7.1(nanostores@0.9.5)(react@18.2.0)
'@types/react': '@types/react':
specifier: ^18.2.55 specifier: ^18.2.56
version: 18.2.55 version: 18.2.58
'@types/react-dom': '@types/react-dom':
specifier: ^18.2.19 specifier: ^18.2.19
version: 18.2.19 version: 18.2.19
@ -45,8 +45,8 @@ dependencies:
specifier: ^3.0.5 specifier: ^3.0.5
version: 3.0.5 version: 3.0.5
lucide-react: lucide-react:
specifier: ^0.331.0 specifier: ^0.334.0
version: 0.331.0(react@18.2.0) version: 0.334.0(react@18.2.0)
nanoid: nanoid:
specifier: ^5.0.5 specifier: ^5.0.5
version: 5.0.5 version: 5.0.5
@ -73,7 +73,7 @@ dependencies:
version: 18.2.0(react@18.2.0) version: 18.2.0(react@18.2.0)
reactflow: reactflow:
specifier: ^11.10.4 specifier: ^11.10.4
version: 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) version: 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
rehype-external-links: rehype-external-links:
specifier: ^3.0.0 specifier: ^3.0.0
version: 3.0.0 version: 3.0.0
@ -90,8 +90,8 @@ dependencies:
specifier: ^3.4.1 specifier: ^3.4.1
version: 3.4.1 version: 3.4.1
zustand: zustand:
specifier: ^4.5.0 specifier: ^4.5.1
version: 4.5.0(@types/react@18.2.55)(react@18.2.0) version: 4.5.1(@types/react@18.2.58)(react@18.2.0)
devDependencies: devDependencies:
'@playwright/test': '@playwright/test':
@ -185,7 +185,7 @@ packages:
prismjs: 1.29.0 prismjs: 1.29.0
dev: false dev: false
/@astrojs/react@3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0)(vite@5.0.12): /@astrojs/react@3.0.10(@types/react-dom@18.2.19)(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)(vite@5.1.3):
resolution: {integrity: sha512-uGRIwKMAn7tva2vxXMyoVIGxWFr0rjZ8ZWIlkTG/vIpnAjD2nM8Cz6B8j7yzj176jvl6gZ6xTbTVPm09aeK0Yw==} resolution: {integrity: sha512-uGRIwKMAn7tva2vxXMyoVIGxWFr0rjZ8ZWIlkTG/vIpnAjD2nM8Cz6B8j7yzj176jvl6gZ6xTbTVPm09aeK0Yw==}
engines: {node: '>=18.14.1'} engines: {node: '>=18.14.1'}
peerDependencies: peerDependencies:
@ -194,9 +194,9 @@ packages:
react: ^17.0.2 || ^18.0.0 react: ^17.0.2 || ^18.0.0
react-dom: ^17.0.2 || ^18.0.0 react-dom: ^17.0.2 || ^18.0.0
dependencies: dependencies:
'@types/react': 18.2.55 '@types/react': 18.2.58
'@types/react-dom': 18.2.19 '@types/react-dom': 18.2.19
'@vitejs/plugin-react': 4.2.1(vite@5.0.12) '@vitejs/plugin-react': 4.2.1(vite@5.1.3)
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
ultrahtml: 1.5.2 ultrahtml: 1.5.2
@ -1102,39 +1102,39 @@ packages:
config-chain: 1.1.13 config-chain: 1.1.13
dev: false dev: false
/@reactflow/background@11.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /@reactflow/background@11.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-byj/G9pEC8tN0wT/ptcl/LkEP/BBfa33/SvBkqE4XwyofckqF87lKp573qGlisfnsijwAbpDlf81PuFL41So4Q==} resolution: {integrity: sha512-byj/G9pEC8tN0wT/ptcl/LkEP/BBfa33/SvBkqE4XwyofckqF87lKp573qGlisfnsijwAbpDlf81PuFL41So4Q==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
dependencies: dependencies:
'@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4 classcat: 5.0.4
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
dev: false dev: false
/@reactflow/controls@11.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /@reactflow/controls@11.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-e8nWplbYfOn83KN1BrxTXS17+enLyFnjZPbyDgHSRLtI5ZGPKF/8iRXV+VXb2LFVzlu4Wh3la/pkxtfP/0aguA==} resolution: {integrity: sha512-e8nWplbYfOn83KN1BrxTXS17+enLyFnjZPbyDgHSRLtI5ZGPKF/8iRXV+VXb2LFVzlu4Wh3la/pkxtfP/0aguA==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
dependencies: dependencies:
'@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4 classcat: 5.0.4
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
dev: false dev: false
/@reactflow/core@11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /@reactflow/core@11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-j3i9b2fsTX/sBbOm+RmNzYEFWbNx4jGWGuGooh2r1jQaE2eV+TLJgiG/VNOp0q5mBl9f6g1IXs3Gm86S9JfcGw==} resolution: {integrity: sha512-j3i9b2fsTX/sBbOm+RmNzYEFWbNx4jGWGuGooh2r1jQaE2eV+TLJgiG/VNOp0q5mBl9f6g1IXs3Gm86S9JfcGw==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
@ -1150,19 +1150,19 @@ packages:
d3-zoom: 3.0.0 d3-zoom: 3.0.0
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
dev: false dev: false
/@reactflow/minimap@11.7.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /@reactflow/minimap@11.7.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-le95jyTtt3TEtJ1qa7tZ5hyM4S7gaEQkW43cixcMOZLu33VAdc2aCpJg/fXcRrrf7moN2Mbl9WIMNXUKsp5ILA==} resolution: {integrity: sha512-le95jyTtt3TEtJ1qa7tZ5hyM4S7gaEQkW43cixcMOZLu33VAdc2aCpJg/fXcRrrf7moN2Mbl9WIMNXUKsp5ILA==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
dependencies: dependencies:
'@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
'@types/d3-selection': 3.0.10 '@types/d3-selection': 3.0.10
'@types/d3-zoom': 3.0.8 '@types/d3-zoom': 3.0.8
classcat: 5.0.4 classcat: 5.0.4
@ -1170,41 +1170,41 @@ packages:
d3-zoom: 3.0.0 d3-zoom: 3.0.0
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
dev: false dev: false
/@reactflow/node-resizer@2.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /@reactflow/node-resizer@2.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-HfickMm0hPDIHt9qH997nLdgLt0kayQyslKE0RS/GZvZ4UMQJlx/NRRyj5y47Qyg0NnC66KYOQWDM9LLzRTnUg==} resolution: {integrity: sha512-HfickMm0hPDIHt9qH997nLdgLt0kayQyslKE0RS/GZvZ4UMQJlx/NRRyj5y47Qyg0NnC66KYOQWDM9LLzRTnUg==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
dependencies: dependencies:
'@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4 classcat: 5.0.4
d3-drag: 3.0.0 d3-drag: 3.0.0
d3-selection: 3.0.0 d3-selection: 3.0.0
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
dev: false dev: false
/@reactflow/node-toolbar@1.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /@reactflow/node-toolbar@1.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-VmgxKmToax4sX1biZ9LXA7cj/TBJ+E5cklLGwquCCVVxh+lxpZGTBF3a5FJGVHiUNBBtFsC8ldcSZIK4cAlQww==} resolution: {integrity: sha512-VmgxKmToax4sX1biZ9LXA7cj/TBJ+E5cklLGwquCCVVxh+lxpZGTBF3a5FJGVHiUNBBtFsC8ldcSZIK4cAlQww==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
dependencies: dependencies:
'@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
classcat: 5.0.4 classcat: 5.0.4
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
zustand: 4.5.0(@types/react@18.2.55)(react@18.2.0) zustand: 4.5.1(@types/react@18.2.58)(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@types/react' - '@types/react'
- immer - immer
@ -1700,11 +1700,11 @@ packages:
/@types/react-dom@18.2.19: /@types/react-dom@18.2.19:
resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==} resolution: {integrity: sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA==}
dependencies: dependencies:
'@types/react': 18.2.55 '@types/react': 18.2.58
dev: false dev: false
/@types/react@18.2.55: /@types/react@18.2.58:
resolution: {integrity: sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==} resolution: {integrity: sha512-TaGvMNhxvG2Q0K0aYxiKfNDS5m5ZsoIBBbtfUorxdH4NGSXIlYvZxLJI+9Dd3KjeB3780bciLyAb7ylO8pLhPw==}
dependencies: dependencies:
'@types/prop-types': 15.7.11 '@types/prop-types': 15.7.11
'@types/scheduler': 0.16.8 '@types/scheduler': 0.16.8
@ -1733,7 +1733,7 @@ packages:
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
dev: false dev: false
/@vitejs/plugin-react@4.2.1(vite@5.0.12): /@vitejs/plugin-react@4.2.1(vite@5.1.3):
resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies: peerDependencies:
@ -1744,7 +1744,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7) '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7)
'@types/babel__core': 7.20.5 '@types/babel__core': 7.20.5
react-refresh: 0.14.0 react-refresh: 0.14.0
vite: 5.0.12 vite: 5.1.3
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false dev: false
@ -3996,8 +3996,8 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
dev: false dev: false
/lucide-react@0.331.0(react@18.2.0): /lucide-react@0.334.0(react@18.2.0):
resolution: {integrity: sha512-CHFJ0ve9vaZ7bB2VRAl27SlX1ELh6pfNC0jS96qGpPEEzLkLDGq4pDBFU8RhOoRMqsjXqTzLm9U6bZ1OcIHq7Q==} resolution: {integrity: sha512-y0Rv/Xx6qAq4FutZ3L/efl3O9vl6NC/1p0YOg6mBfRbQ4k1JCE2rz0rnV7WC8Moxq1RY99vLATvjcqUegGJTvA==}
peerDependencies: peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 react: ^16.5.1 || ^17.0.0 || ^18.0.0
dependencies: dependencies:
@ -5543,18 +5543,18 @@ packages:
loose-envify: 1.4.0 loose-envify: 1.4.0
dev: false dev: false
/reactflow@11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0): /reactflow@11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-0CApYhtYicXEDg/x2kvUHiUk26Qur8lAtTtiSlptNKuyEuGti6P1y5cS32YGaUoDMoCqkm/m+jcKkfMOvSCVRA==} resolution: {integrity: sha512-0CApYhtYicXEDg/x2kvUHiUk26Qur8lAtTtiSlptNKuyEuGti6P1y5cS32YGaUoDMoCqkm/m+jcKkfMOvSCVRA==}
peerDependencies: peerDependencies:
react: '>=17' react: '>=17'
react-dom: '>=17' react-dom: '>=17'
dependencies: dependencies:
'@reactflow/background': 11.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/background': 11.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
'@reactflow/controls': 11.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/controls': 11.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
'@reactflow/core': 11.10.4(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/core': 11.10.4(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
'@reactflow/minimap': 11.7.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/minimap': 11.7.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
'@reactflow/node-resizer': 2.2.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/node-resizer': 2.2.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
'@reactflow/node-toolbar': 1.3.9(@types/react@18.2.55)(react-dom@18.2.0)(react@18.2.0) '@reactflow/node-toolbar': 1.3.9(@types/react@18.2.58)(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0(react@18.2.0) react-dom: 18.2.0(react@18.2.0)
transitivePeerDependencies: transitivePeerDependencies:
@ -6745,41 +6745,6 @@ packages:
vfile-message: 4.0.2 vfile-message: 4.0.2
dev: false dev: false
/vite@5.0.12:
resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
'@types/node': ^18.0.0 || >=20.0.0
less: '*'
lightningcss: ^1.21.0
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
esbuild: 0.19.11
postcss: 8.4.33
rollup: 4.9.6
optionalDependencies:
fsevents: 2.3.3
dev: false
/vite@5.1.3: /vite@5.1.3:
resolution: {integrity: sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==} resolution: {integrity: sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==}
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
@ -6964,8 +6929,8 @@ packages:
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
dev: false dev: false
/zustand@4.5.0(@types/react@18.2.55)(react@18.2.0): /zustand@4.5.1(@types/react@18.2.58)(react@18.2.0):
resolution: {integrity: sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==} resolution: {integrity: sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg==}
engines: {node: '>=12.7.0'} engines: {node: '>=12.7.0'}
peerDependencies: peerDependencies:
'@types/react': '>=16.8' '@types/react': '>=16.8'
@ -6979,7 +6944,7 @@ packages:
react: react:
optional: true optional: true
dependencies: dependencies:
'@types/react': 18.2.55 '@types/react': 18.2.58
react: 18.2.0 react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0) use-sync-external-store: 1.2.0(react@18.2.0)
dev: false dev: false

@ -6,28 +6,32 @@ export interface Props {
} }
const { guide } = Astro.props; const { guide } = Astro.props;
const { frontmatter } = guide; const { frontmatter, author } = guide;
const { author } = frontmatter;
--- ---
<div class='bg-white border-b py-5 sm:py-12'> <div class='border-b bg-white py-5 sm:py-12'>
<div class='container text-left sm:text-center'> <div class='container text-left sm:text-center'>
<p <p
class='text-gray-400 hidden sm:flex items-center justify-start sm:justify-center' class='hidden items-center justify-start text-gray-400 sm:flex sm:justify-center'
> >
<a {
href={author.url} author?.frontmatter && (
target='_blank' <>
class='font-medium hover:text-gray-600 inline-flex items-center hover:underline' <a
> href={`/authors/${author.id}`}
<img class='inline-flex items-center font-medium hover:text-gray-600 hover:underline'
alt={author.name} >
src={author.imageUrl} <img
class='w-5 h-5 inline mr-2 rounded-full' alt={author.frontmatter.name}
/> src={author.frontmatter.imageUrl}
{author.name} class='mr-2 inline h-5 w-5 rounded-full'
</a> />
<span class='mx-1.5'>&middot;</span> {author.frontmatter.name}
</a>
<span class='mx-1.5'>&middot;</span>
</>
)
}
<span class='capitalize'>{frontmatter.type} Guide</span> <span class='capitalize'>{frontmatter.type} Guide</span>
<span class='mx-1.5'>&middot;</span> <span class='mx-1.5'>&middot;</span>
<a <a
@ -36,10 +40,10 @@ const { author } = frontmatter;
target='_blank'>Improve this Guide</a target='_blank'>Improve this Guide</a
> >
</p> </p>
<h1 class='text-2xl sm:text-5xl my-0 sm:my-3.5 font-bold'> <h1 class='my-0 text-2xl font-bold sm:my-3.5 sm:text-5xl'>
{frontmatter.title} {frontmatter.title}
</h1> </h1>
<p class='hidden sm:block text-gray-400 text-xl'> <p class='hidden text-xl text-gray-400 sm:block'>
{frontmatter.description} {frontmatter.description}
</p> </p>
</div> </div>

@ -1,5 +1,5 @@
--- ---
import type { GuideFileType } from "../lib/guide"; import type { GuideFileType } from '../lib/guide';
export interface Props { export interface Props {
guide: GuideFileType; guide: GuideFileType;
@ -11,30 +11,34 @@ const { frontmatter, id } = guide;
<a <a
class:list={[ class:list={[
"block no-underline py-2 group text-md items-center text-gray-600 hover:text-blue-600 flex justify-between border-b", 'text-md group block flex items-center justify-between border-b py-2 text-gray-600 no-underline hover:text-blue-600',
]} ]}
href={frontmatter.excludedBySlug ? frontmatter.excludedBySlug : `/guides/${id}`} href={frontmatter.excludedBySlug
? frontmatter.excludedBySlug
: `/guides/${id}`}
> >
<span class="group-hover:translate-x-2 transition-transform"> <span
class='text-sm transition-transform group-hover:translate-x-2 md:text-base'
>
{frontmatter.title} {frontmatter.title}
{ {
frontmatter.isNew && ( frontmatter.isNew && (
<span class="bg-green-300 text-green-900 text-xs font-medium px-1.5 py-0.5 rounded-sm uppercase ml-1.5"> <span class='ml-1.5 rounded-sm bg-green-300 px-1.5 py-0.5 text-xs font-medium uppercase text-green-900'>
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>
</span> </span>
) )
} }
</span> </span>
<span class="capitalize text-gray-500 text-xs hidden sm:block"> <span class='hidden text-xs capitalize text-gray-500 sm:block'>
{frontmatter.type} {frontmatter.type}
</span> </span>
<span class="text-gray-400 text-xs block sm:hidden"> &raquo;</span> <span class='block text-xs text-gray-400 sm:hidden'> &raquo;</span>
</a> </a>

@ -0,0 +1,11 @@
---
name: 'Fernando Doglio'
imageUrl: '/authors/fernando.jpeg'
social:
twitter: 'https://twitter.com/deleteman123'
linkedin: 'https://www.linkedin.com/in/fernandodoglio'
---
With two decades of experience in Software Development, Fernando Doglio excels in diverse languages like Ruby, Perl, PHP, Python, and JavaScript. He's led teams in crafting scalable architectures for both in-house and cloud infrastructures.
An author of 8 technical books and over 250 articles, Fernando's current role as a Dev Advocate allows him to blend his passion for coding with content creation, enhancing developer experiences with products through engaging outreach.

@ -0,0 +1,13 @@
---
name: 'Kamran Ahmed'
imageUrl: '/authors/kamran.jpeg'
social:
linkedin: 'https://www.linkedin.com/in/kamrify'
twitter: 'https://twitter.com/kamrify'
github: 'https://github.com/kamranahmedse'
website: 'https://kamranahmed.info'
---
Kamran is the founder of **roadmap.sh**. He has a decade long experience working mostly with startups and scale-ups. Over the years, he has worked with a variety of technologies in a variety of domains and have worn several different hats. He is working full time on roadmap.sh at the moment.
He is also a Google Developer Expert and a GitHub Star. He is a huge proponent of open-source, and has authored several popular open-source projects. He is [the second most starred developer](https://twitter.com/kamrify/status/1750345095587754382) on GitHub globally.

@ -1,10 +1,7 @@
--- ---
title: 'Asymptotic Notation' title: 'Asymptotic Notation'
description: 'Learn the basics of measuring the time and space complexity of algorithms' description: 'Learn the basics of measuring the time and space complexity of algorithms'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Asymptotic Notation - roadmap.sh' title: 'Asymptotic Notation - roadmap.sh'
description: 'Learn the basics of measuring the time and space complexity of algorithms' description: 'Learn the basics of measuring the time and space complexity of algorithms'

@ -1,10 +1,7 @@
--- ---
title: 'Async and Defer Script Loading' title: 'Async and Defer Script Loading'
description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.' description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Async and Defer Script Loading - roadmap.sh' title: 'Async and Defer Script Loading - roadmap.sh'
description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.' description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.'

@ -1,10 +1,7 @@
--- ---
title: 'The 5 Best Backend Development Languages to Master (2024)' title: 'The 5 Best Backend Development Languages to Master (2024)'
description: 'Discover the best backend development languages to master in 2024.' description: 'Discover the best backend development languages to master in 2024.'
author: authorId: fernando
name: 'Fernando Doglio'
url: 'https://twitter.com/deleteman123'
imageUrl: '/authors/fernando.jpeg'
excludedBySlug: '/backend/languages' excludedBySlug: '/backend/languages'
seo: seo:
title: 'The 5 Best Backend Development Languages to Master (2024)' title: 'The 5 Best Backend Development Languages to Master (2024)'
@ -116,7 +113,7 @@ What makes Python extra appealing, especially for beginners, is the fact that re
One of Python's standout features is its beginner-friendly syntax, making it an ideal language for those new to programming. The emphasis on readability and the absence of complex syntax (for the most part), eases the learning curve, enabling new developers to quickly grasp fundamental concepts. One of Python's standout features is its beginner-friendly syntax, making it an ideal language for those new to programming. The emphasis on readability and the absence of complex syntax (for the most part), eases the learning curve, enabling new developers to quickly grasp fundamental concepts.
Python's community plays a critical role in its accessibility. Abundant learning resources, tutorials, and documentation are readily available, empowering beginners to progress from basic programming principles to advanced backend development seamlessly. Online platforms like Codecademy, Coursera, realpython.com, and even Google offer comprehensive courses tailored to all skill levels. Python's community plays a critical role in its accessibility. Abundant learning resources, tutorials, and documentation are readily available, empowering beginners to progress from basic programming principles to advanced backend development seamlessly. Online platforms like Codecademy, Coursera, realpython.com, and even Google offer comprehensive courses tailored to all skill levels.
#### Practical Applications and Popular Frameworks #### Practical Applications and Popular Frameworks
@ -154,7 +151,7 @@ Java has a massive presence and for good reason (according to [JetBrain’s surv
#### Is it worth learning Java? #### Is it worth learning Java?
Now, learning Java, (a strongly typed, object oriented programming language (OOP), is a journey worth taking, but it's not a walk in the park. It's a bit like climbing a mountain – you start at the bottom with the basics, and as you ascend, you get into the nitty-gritty of things like object-oriented programming. The process will force you to learn a lot, which is a great thing, by the end you’ll have a lot of understanding of mechanics and concepts around OOP that can be extrapolated into other languages. However, that can also be overwhelming to some developers who just want to learn by building mini-projects. In those situations, the learning curve of Java might be too long (not steep, but long because there is a lot more to cover than with alternatives such as Python or JavaScript). Now, learning Java, (a strongly typed, object oriented programming language (OOP), is a journey worth taking, but it's not a walk in the park. It's a bit like climbing a mountain – you start at the bottom with the basics, and as you ascend, you get into the nitty-gritty of things like object-oriented programming. The process will force you to learn a lot, which is a great thing, by the end you’ll have a lot of understanding of mechanics and concepts around OOP that can be extrapolated into other languages. However, that can also be overwhelming to some developers who just want to learn by building mini-projects. In those situations, the learning curve of Java might be too long (not steep, but long because there is a lot more to cover than with alternatives such as Python or JavaScript).
That said, the community is big and there are tons of resources, from online courses to forums, helping you navigate the Java landscape. And good reason, considering Java has been around for quite a while. That said, the community is big and there are tons of resources, from online courses to forums, helping you navigate the Java landscape. And good reason, considering Java has been around for quite a while.
@ -205,7 +202,7 @@ Now, if on the other hand, you’re looking to build the frontend and the backen
#### Does it make sense to pick up JavaScript as a backend language? #### Does it make sense to pick up JavaScript as a backend language?
The answer to this question is always going to be “yes”, whether you’re coming from the frontend and you already have JS experience or if you’re picking it up from scratch. In fact, according to [StackOverflow’s 2023 survey, JavaScript is the most used language by professionals](https://survey.stackoverflow.co/2023/#most-popular-technologies-language-prof) (with 65.85% of the votes). The answer to this question is always going to be “yes”, whether you’re coming from the frontend and you already have JS experience or if you’re picking it up from scratch. In fact, according to [StackOverflow’s 2023 survey, JavaScript is the most used language by professionals](https://survey.stackoverflow.co/2023/#most-popular-technologies-language-prof) (with 65.85% of the votes).
![JavaScript Interest](/guides/backend-languages/javascript-interest.png) ![JavaScript Interest](/guides/backend-languages/javascript-interest.png)
@ -383,12 +380,3 @@ In the end, there are many backend programming languages to choose from, and wha
You’re the one who gets to decide, but just know that no matter what you choose, getting started in backend development is a one-way street. You’ll be learning from this moment on, and you’ll be jumping from one language to the other as the field evolves. You’re the one who gets to decide, but just know that no matter what you choose, getting started in backend development is a one-way street. You’ll be learning from this moment on, and you’ll be jumping from one language to the other as the field evolves.
Remember that there is a very detailed version of a [backend roadmap here](https://roadmap.sh/backend), it might be a great place to get started! And if you’re also interested in frontend development, there is an [equally handy roadmap](https://roadmap.sh/frontend) here as well! Remember that there is a very detailed version of a [backend roadmap here](https://roadmap.sh/backend), it might be a great place to get started! And if you’re also interested in frontend development, there is an [equally handy roadmap](https://roadmap.sh/frontend) here as well!

@ -1,10 +1,7 @@
--- ---
title: 'Basic Authentication' title: 'Basic Authentication'
description: 'Understand what is basic authentication and how it is implemented' description: 'Understand what is basic authentication and how it is implemented'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Basic Authentication - roadmap.sh' title: 'Basic Authentication - roadmap.sh'
description: 'Understand what is basic authentication and how it is implemented' description: 'Understand what is basic authentication and how it is implemented'

@ -1,10 +1,7 @@
--- ---
title: 'Basics of Authentication' title: 'Basics of Authentication'
description: 'Learn the basics of Authentication and Authorization' description: 'Learn the basics of Authentication and Authorization'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Basics of Authentication - roadmap.sh' title: 'Basics of Authentication - roadmap.sh'
description: 'Learn the basics of Authentication and Authorization' description: 'Learn the basics of Authentication and Authorization'

@ -1,10 +1,7 @@
--- ---
title: 'Big-O Notation' title: 'Big-O Notation'
description: 'Easy to understand explanation of Big-O notation without any fancy terms' description: 'Easy to understand explanation of Big-O notation without any fancy terms'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Big-O Notation - roadmap.sh' title: 'Big-O Notation - roadmap.sh'
description: 'Easy to understand explanation of Big-O notation without any fancy terms' description: 'Easy to understand explanation of Big-O notation without any fancy terms'

@ -1,10 +1,7 @@
--- ---
title: 'Character Encodings' title: 'Character Encodings'
description: 'Covers the basics of character encodings and explains ASCII vs Unicode' description: 'Covers the basics of character encodings and explains ASCII vs Unicode'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Character Encodings - roadmap.sh' title: 'Character Encodings - roadmap.sh'
description: 'Covers the basics of character encodings and explains ASCII vs Unicode' description: 'Covers the basics of character encodings and explains ASCII vs Unicode'

@ -1,10 +1,7 @@
--- ---
title: 'What is CI and CD?' title: 'What is CI and CD?'
description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.' description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'What is CI and CD? - roadmap.sh' title: 'What is CI and CD? - roadmap.sh'
description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.' description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.'

@ -1,10 +1,7 @@
--- ---
title: 'Consistency Patterns' title: 'Consistency Patterns'
description: 'Everything you need to know about Week, Strong and Eventual Consistency' description: 'Everything you need to know about Week, Strong and Eventual Consistency'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Consistency Patterns - roadmap.sh' title: 'Consistency Patterns - roadmap.sh'
description: 'Everything you need to know about Week, Strong and Eventual Consistency' description: 'Everything you need to know about Week, Strong and Eventual Consistency'

@ -1,10 +1,7 @@
--- ---
title: 'Design Patterns for Humans' title: 'Design Patterns for Humans'
description: 'A language agnostic, ultra-simplified explanation to design patterns' description: 'A language agnostic, ultra-simplified explanation to design patterns'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Design Patterns for Humans - roadmap.sh' title: 'Design Patterns for Humans - roadmap.sh'
description: 'A language agnostic, ultra-simplified explanation to design patterns' description: 'A language agnostic, ultra-simplified explanation to design patterns'

@ -1,10 +1,7 @@
--- ---
title: 'DHCP in One Picture' title: 'DHCP in One Picture'
description: 'Here is what happens when a new device joins the network.' description: 'Here is what happens when a new device joins the network.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'DHCP in One Picture - roadmap.sh' title: 'DHCP in One Picture - roadmap.sh'
description: 'Here is what happens when a new device joins the network.' description: 'Here is what happens when a new device joins the network.'

@ -1,10 +1,7 @@
--- ---
title: 'DNS in One Picture' title: 'DNS in One Picture'
description: 'Quick illustrative guide on how a website is found on the internet.' description: 'Quick illustrative guide on how a website is found on the internet.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'DNS in One Picture - roadmap.sh' title: 'DNS in One Picture - roadmap.sh'
description: 'Quick illustrative guide on how a website is found on the internet.' description: 'Quick illustrative guide on how a website is found on the internet.'

@ -1,10 +1,7 @@
--- ---
title: '5 Free Resources to Master LLMs' title: '5 Free Resources to Master LLMs'
description: 'Dive into the world of LLMs with these free resources' description: 'Dive into the world of LLMs with these free resources'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: '5 Free Resources to Master Language Models (LLMs) - roadmap.sh' title: '5 Free Resources to Master Language Models (LLMs) - roadmap.sh'
description: 'Looking to dive into the fascinating world of Language Models (LLMs)? Discover the top 5 free resources that will help you learn and excel in understanding LLMs. From comprehensive tutorials to interactive courses, this blog post provides you with the ultimate guide to sharpen your skills and unravel the potential of language models. Start your journey today and become a pro in LLMs without spending a dime!' description: 'Looking to dive into the fascinating world of Language Models (LLMs)? Discover the top 5 free resources that will help you learn and excel in understanding LLMs. From comprehensive tutorials to interactive courses, this blog post provides you with the ultimate guide to sharpen your skills and unravel the potential of language models. Start your journey today and become a pro in LLMs without spending a dime!'

@ -1,10 +1,7 @@
--- ---
title: 'Brief History of JavaScript' title: 'Brief History of JavaScript'
description: 'How JavaScript was introduced and evolved over the years' description: 'How JavaScript was introduced and evolved over the years'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Brief History of JavaScript - roadmap.sh' title: 'Brief History of JavaScript - roadmap.sh'
description: 'How JavaScript was introduced and evolved over the years' description: 'How JavaScript was introduced and evolved over the years'

@ -1,10 +1,7 @@
--- ---
title: 'Jump Servers: What, Why and How' title: 'Jump Servers: What, Why and How'
description: 'Learn what is a Jump Server and how to set it up for SSH access.' description: 'Learn what is a Jump Server and how to set it up for SSH access.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Jump Servers: What, Why and How - roadmap.sh' title: 'Jump Servers: What, Why and How - roadmap.sh'
description: 'Learn what is a Jump Server and how to set it up for SSH access.' description: 'Learn what is a Jump Server and how to set it up for SSH access.'

@ -1,10 +1,7 @@
--- ---
title: 'HTTP Basic Authentication' title: 'HTTP Basic Authentication'
description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js' description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'HTTP Basic Authentication - roadmap.sh' title: 'HTTP Basic Authentication - roadmap.sh'
description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js' description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js'

@ -1,10 +1,7 @@
--- ---
title: 'HTTP Caching' title: 'HTTP Caching'
description: 'Everything you need to know about web caching' description: 'Everything you need to know about web caching'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'HTTP Caching - roadmap.sh' title: 'HTTP Caching - roadmap.sh'
description: 'Everything you need to know about web caching' description: 'Everything you need to know about web caching'

@ -1,10 +1,7 @@
--- ---
title: 'Introduction to LLMs' title: 'Introduction to LLMs'
description: 'What are LLMs, how does ChatGPT and other LLMs work?' description: 'What are LLMs, how does ChatGPT and other LLMs work?'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Introduction to LLMs - roadmap.sh' title: 'Introduction to LLMs - roadmap.sh'
description: 'What are LLMs, how does ChatGPT and other LLMs work?' description: 'What are LLMs, how does ChatGPT and other LLMs work?'

@ -1,10 +1,7 @@
--- ---
title: 'Journey to HTTP/2' title: 'Journey to HTTP/2'
description: 'The evolution of HTTP. How it all started and where we stand today' description: 'The evolution of HTTP. How it all started and where we stand today'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Journey to HTTP/2 - roadmap.sh' title: 'Journey to HTTP/2 - roadmap.sh'
description: 'The evolution of HTTP. How it all started and where we stand today' description: 'The evolution of HTTP. How it all started and where we stand today'

@ -1,10 +1,7 @@
--- ---
title: 'JWT Authentication' title: 'JWT Authentication'
description: 'Understand what is JWT authentication and how is it implemented' description: 'Understand what is JWT authentication and how is it implemented'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'JWT Authentication - roadmap.sh' title: 'JWT Authentication - roadmap.sh'
description: 'Understand what is JWT authentication and how is it implemented' description: 'Understand what is JWT authentication and how is it implemented'

@ -1,10 +1,7 @@
--- ---
title: 'Levels of Seniority' title: 'Levels of Seniority'
description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?' description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Levels of Seniority - roadmap.sh' title: 'Levels of Seniority - roadmap.sh'
description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?' description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?'

@ -1,10 +1,7 @@
--- ---
title: 'OAuth — Open Authorization' title: 'OAuth — Open Authorization'
description: 'Learn and understand what is OAuth and how it works' description: 'Learn and understand what is OAuth and how it works'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'OAuth — Open Authorization - roadmap.sh' title: 'OAuth — Open Authorization - roadmap.sh'
description: 'Learn and understand what is OAuth and how it works' description: 'Learn and understand what is OAuth and how it works'

@ -1,10 +1,7 @@
--- ---
title: 'Random Numbers: Are they?' title: 'Random Numbers: Are they?'
description: 'Learn how they are generated and why they may not be truly random.' description: 'Learn how they are generated and why they may not be truly random.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Random Numbers: Are they? - roadmap.sh' title: 'Random Numbers: Are they? - roadmap.sh'
description: 'Learn how they are generated and why they may not be truly random.' description: 'Learn how they are generated and why they may not be truly random.'

@ -1,10 +1,7 @@
--- ---
title: 'Scaling Databases' title: 'Scaling Databases'
description: 'Learn the ups and downs of different database scaling strategies' description: 'Learn the ups and downs of different database scaling strategies'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Scaling Databases - roadmap.sh' title: 'Scaling Databases - roadmap.sh'
description: 'Learn the ups and downs of different database scaling strategies' description: 'Learn the ups and downs of different database scaling strategies'

@ -1,10 +1,7 @@
--- ---
title: 'Session Based Authentication' title: 'Session Based Authentication'
description: 'Understand what is session based authentication and how it is implemented' description: 'Understand what is session based authentication and how it is implemented'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Session Based Authentication - roadmap.sh' title: 'Session Based Authentication - roadmap.sh'
description: 'Understand what is session based authentication and how it is implemented' description: 'Understand what is session based authentication and how it is implemented'

@ -1,10 +1,7 @@
--- ---
title: 'Session Based Authentication' title: 'Session Based Authentication'
description: 'Learn what is Session Based Authentication and how to implement it in Node.js' description: 'Learn what is Session Based Authentication and how to implement it in Node.js'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Session Based Authentication - roadmap.sh' title: 'Session Based Authentication - roadmap.sh'
description: 'Learn what is Session Based Authentication and how to implement it in Node.js' description: 'Learn what is Session Based Authentication and how to implement it in Node.js'

@ -1,10 +1,7 @@
--- ---
title: "Guide to Let's Encrypt SSL Setup" title: "Guide to Let's Encrypt SSL Setup"
description: "Learn how to protect your website using Let's Encrypt SSL Certificates." description: "Learn how to protect your website using Let's Encrypt SSL Certificates."
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: "Guide to Let's Encrypt SSL Setup - roadmap.sh" title: "Guide to Let's Encrypt SSL Setup - roadmap.sh"
description: "Learn how to protect your website using Let's Encrypt SSL Certificates." description: "Learn how to protect your website using Let's Encrypt SSL Certificates."

@ -1,10 +1,7 @@
--- ---
title: 'Single Command Database Setup' title: 'Single Command Database Setup'
description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command' description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Single Command Database Setup - roadmap.sh' title: 'Single Command Database Setup - roadmap.sh'
description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command' description: 'Learn how to run MySQL, PostgreSQL, or MongoDB in Docker with single Command'

@ -1,10 +1,7 @@
--- ---
title: 'SSL vs TLS vs SSH' title: 'SSL vs TLS vs SSH'
description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH' description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'SSL vs TLS vs SSH - roadmap.sh' title: 'SSL vs TLS vs SSH - roadmap.sh'
description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH' description: 'Quick tidbit on the differences between SSL, TLS, HTTPS and SSH'

@ -1,10 +1,7 @@
--- ---
title: 'SSO — Single Sign On' title: 'SSO — Single Sign On'
description: 'Learn the basics of SAML and understand how does Single Sign On work.' description: 'Learn the basics of SAML and understand how does Single Sign On work.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'SSO — Single Sign On - roadmap.sh' title: 'SSO — Single Sign On - roadmap.sh'
description: 'Learn the basics of SAML and understand how does Single Sign On work.' description: 'Learn the basics of SAML and understand how does Single Sign On work.'

@ -1,10 +1,7 @@
--- ---
title: 'Token Based Authentication' title: 'Token Based Authentication'
description: 'Understand what is token based authentication and how it is implemented' description: 'Understand what is token based authentication and how it is implemented'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Token Based Authentication - roadmap.sh' title: 'Token Based Authentication - roadmap.sh'
description: 'Understand what is token based authentication and how it is implemented' description: 'Understand what is token based authentication and how it is implemented'

@ -1,10 +1,7 @@
--- ---
title: 'Unfamiliar Codebase' title: 'Unfamiliar Codebase'
description: 'Tips on getting familiar with an unfamiliar codebase' description: 'Tips on getting familiar with an unfamiliar codebase'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'Unfamiliar Codebase - roadmap.sh' title: 'Unfamiliar Codebase - roadmap.sh'
description: 'Tips on getting familiar with an unfamiliar codebase' description: 'Tips on getting familiar with an unfamiliar codebase'

@ -1,10 +1,7 @@
--- ---
title: 'What are Web Vitals?' title: 'What are Web Vitals?'
description: 'Learn what are the core web vitals and how to measure them.' description: 'Learn what are the core web vitals and how to measure them.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'What are Web Vitals? - roadmap.sh' title: 'What are Web Vitals? - roadmap.sh'
description: 'Learn what are the core web vitals and how to measure them.' description: 'Learn what are the core web vitals and how to measure them.'

@ -1,10 +1,7 @@
--- ---
title: 'How does the internet work?' title: 'How does the internet work?'
description: 'Learn the basics of internet and everything involved with this short video series' description: 'Learn the basics of internet and everything involved with this short video series'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'How does the internet work? - roadmap.sh' title: 'How does the internet work? - roadmap.sh'
description: 'Learn the basics of internet and everything involved with this short video series' description: 'Learn the basics of internet and everything involved with this short video series'

@ -1,10 +1,7 @@
--- ---
title: 'SLIs, SLOs and SLAs' title: 'SLIs, SLOs and SLAs'
description: 'Learn what are different indicators for performance identification of any service.' description: 'Learn what are different indicators for performance identification of any service.'
author: authorId: 'kamran'
name: 'Kamran Ahmed'
url: 'https://twitter.com/kamrify'
imageUrl: '/authors/kamranahmedse.jpeg'
seo: seo:
title: 'SLIs, SLOs and SLAs - roadmap.sh' title: 'SLIs, SLOs and SLAs - roadmap.sh'
description: 'Learn what are different indicators for performance identification of any service.' description: 'Learn what are different indicators for performance identification of any service.'

1
src/env.d.ts vendored

@ -1,4 +1,3 @@
/// <reference types="astro/client" />
import 'astro/client'; import 'astro/client';
interface ImportMetaEnv { interface ImportMetaEnv {

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 98 96" xmlns:v="https://vecta.io/nano"><path fill-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362l-.08-9.127c-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126l-.08 13.526c0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 98 96" xmlns:v="https://vecta.io/nano"><path fill-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362l-.08-9.127c-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126l-.08 13.526c0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="currentColor"/></svg>

Before

Width:  |  Height:  |  Size: 941 B

After

Width:  |  Height:  |  Size: 946 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm9.567 9.098c-.059-.058-.127-.108-.206-.138-.258-.101-1.35.603-1.515.256-.108-.231-.327.148-.578.008-.121-.067-.459-.52-.611-.465-.312.112.479.974.694 1.087.203-.154.86-.469 1.002-.039.271.812-.745 1.702-1.264 2.171-.775.702-.63-.454-1.159-.86-.277-.213-.274-.667-.555-.824-.125-.071-.7-.732-.694-.821l-.017.167c-.095.072-.297-.27-.319-.325 0 .298.485.772.646 1.011.273.409.42 1.005.756 1.339.179.18.866.923 1.045.908l.921-.437c.649.154-1.531 3.237-1.738 3.619-.171.321.139 1.112.114 1.49-.029.437-.374.579-.7.817-.35.255-.268.752-.562.934-.521.321-.897 1.366-1.639 1.361-.219-.001-1.151.364-1.273.007-.095-.258-.223-.455-.356-.71-.131-.25-.015-.51-.175-.731-.11-.154-.479-.502-.513-.684-.002-.157.118-.632.283-.715.231-.118.044-.462.016-.663-.048-.357-.27-.652-.535-.859-.393-.302-.189-.542-.098-.974 0-.206-.126-.476-.402-.396-.57.166-.396-.445-.812-.417-.299.021-.543.211-.821.295-.349.104-.707-.083-1.053-.126-1.421-.179-1.885-1.804-1.514-2.976.037-.192-.115-.547-.048-.696.159-.352.485-.752.768-1.021.16-.152.365-.113.553-.231.29-.182.294-.558.578-.789.404-.328.956-.321 1.482-.392.281-.037 1.35-.268 1.518-.06 0 .039.193.611-.019.578.438.023 1.061.756 1.476.585.213-.089.135-.744.573-.427.265.19 1.45.275 1.696.07.152-.125.236-.939.053-1.031.117.116-.618.125-.686.099-.122-.044-.235.115-.43.025.117.055-.651-.358-.22-.674-.181.132-.349-.037-.544.109-.135.109.062.181-.13.277-.305.155-.535-.53-.649-.607-.118-.077-1.024-.713-.777-.298l.797.793c-.04.026-.209-.289-.209-.059.053-.136.02.585-.105.35-.056-.09.091-.14.006-.271 0-.085-.23-.169-.275-.228-.126-.157-.462-.502-.644-.585-.05-.024-.771.088-.832.111-.071.099-.131.203-.181.314-.149.055-.29.127-.423.216l-.159.356c-.068.061-.772.294-.776.303.03-.076-.492-.172-.457-.324.038-.167.215-.687.169-.877-.048-.199 1.085.287 1.158-.238.029-.227.047-.492-.316-.531.069.008.702-.249.807-.364.148-.169.486-.447.731-.447.286 0 .225-.417.356-.622.133.053-.071.38.088.512-.01-.104.45.057.494.033.105-.056.691-.023.601-.299-.101-.28.052-.197.183-.255-.02.008.248-.458.363-.456-.104-.089-.398.112-.516.103-.308-.024-.177-.525-.061-.672.09-.116-.246-.258-.25-.036-.006.332-.314.633-.243 1.075.109.666-.743-.161-.816-.115-.283.172-.515-.216-.368-.449.149-.238.51-.226.659-.48.104-.179.227-.389.388-.524.541-.454.689-.091 1.229-.042.526.048.178.125.105.327-.07.192.289.261.413.1.071-.092.232-.326.301-.499.07-.175.578-.2.527-.365 2.72 1.148 4.827 3.465 5.694 6.318zm-11.113-3.779l.068-.087.073-.019c.042-.034.086-.118.151-.104.043.009.146.095.111.148-.037.054-.066-.049-.081.101-.018.169-.188.167-.313.222-.087.037-.175-.018-.09-.104l.088-.108-.007-.049zm.442.245c.046-.045.138-.008.151-.094.014-.084.078-.178-.008-.335-.022-.042.116-.082.051-.137l-.109.032s.155-.668.364-.366l-.089.103c.135.134.172.47.215.687.127.066.324.078.098.192.117-.02-.618.314-.715.178-.072-.083.317-.139.307-.173-.004-.011-.317-.02-.265-.087zm1.43-3.547l-.356.326c-.36.298-1.28.883-1.793.705-.524-.18-1.647.667-1.826.673-.067.003.002-.641.36-.689-.141.021.993-.575 1.185-.805.678-.146 1.381-.227 2.104-.227l.326.017zm-5.086 1.19c.07.082.278.092-.026.288-.183.11-.377.809-.548.809-.51.223-.542-.439-1.109.413-.078.115-.395.158-.644.236.685-.688 1.468-1.279 2.327-1.746zm-5.24 8.793c0-.541.055-1.068.139-1.586l.292.185c.113.135.113.719.169.911.139.482.484.751.748 1.19.155.261.414.923.332 1.197.109-.179 1.081.824 1.259 1.033.418.492.74 1.088.061 1.574-.219.158.334 1.14.049 1.382l-.365.094c-.225.138-.235.397-.166.631-1.562-1.765-2.518-4.076-2.518-6.611zm14.347-5.823c.083-.01-.107.167-.107.167.033.256.222.396.581.527.437.157.038.455-.213.385-.139-.039-.854-.255-.879.025 0 .167-.679.001-.573-.175.073-.119.05-.387.186-.562.193-.255.38-.116.386.032-.001.394.398-.373.619-.399z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2344_20)">
<path d="M0 0V24H24V0H0ZM8 19H5V8H8V19ZM6.5 6.732C5.534 6.732 4.75 5.942 4.75 4.968C4.75 3.994 5.534 3.204 6.5 3.204C7.466 3.204 8.25 3.994 8.25 4.968C8.25 5.942 7.467 6.732 6.5 6.732ZM20 19H17V13.396C17 10.028 13 10.283 13 13.396V19H10V8H13V9.765C14.397 7.179 20 6.988 20 12.241V19Z" fill="currentColor"/>
</g>
<defs>
<clipPath id="clip0_2344_20">
<rect width="24" height="24" rx="2" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 611 B

@ -0,0 +1,73 @@
import type { MarkdownFileType } from './file';
export interface AuthorFrontmatter {
name: string;
imageUrl: string;
social: {
twitter: string;
github: string;
linkedin: string;
website: string;
};
}
export type AuthorFileType = MarkdownFileType<AuthorFrontmatter> & {
id: string;
};
function authorPathToId(filePath: string): string {
const fileName = filePath.split('/').pop() || '';
return fileName.replace('.md', '');
}
/**
* Gets the IDs of all the authors available on the website
*
* @returns string[] Array of author IDs
*/
export async function getAuthorIds() {
const authorFiles = import.meta.glob<AuthorFileType>(
'/src/data/authors/*.md',
{
eager: true,
},
);
console.log(Object.keys(authorFiles));
return Object.keys(authorFiles).map(authorPathToId);
}
export async function getAllAuthors(): Promise<AuthorFileType[]> {
const authorFilesMap: Record<string, AuthorFileType> =
import.meta.glob<AuthorFileType>('/src/data/authors/*.md', {
eager: true,
});
const authorFiles = Object.values(authorFilesMap);
return authorFiles.map((authorFile) => ({
...authorFile,
id: authorPathToId(authorFile.file),
}));
}
export async function getAuthorById(id: string): Promise<AuthorFileType> {
const authorFilesMap: Record<string, AuthorFileType> =
import.meta.glob<AuthorFileType>('/src/data/authors/*.md', {
eager: true,
});
const authorFile = Object.values(authorFilesMap).find((authorFile) => {
return authorPathToId(authorFile.file) === id;
});
if (!authorFile) {
throw new Error(`Author with ID ${id} not found`);
}
return {
...authorFile,
id: authorPathToId(authorFile.file),
};
}

@ -1,13 +1,10 @@
import type { MarkdownFileType } from './file'; import type { MarkdownFileType } from './file';
import { type AuthorFileType, getAllAuthors } from './author.ts';
export interface GuideFrontmatter { export interface GuideFrontmatter {
title: string; title: string;
description: string; description: string;
author: { authorId: string;
name: string;
url: string;
imageUrl: string;
};
canonicalUrl?: string; canonicalUrl?: string;
// alternate path where this guide has been published // alternate path where this guide has been published
excludedBySlug?: string; excludedBySlug?: string;
@ -27,6 +24,7 @@ export interface GuideFrontmatter {
export type GuideFileType = MarkdownFileType<GuideFrontmatter> & { export type GuideFileType = MarkdownFileType<GuideFrontmatter> & {
id: string; id: string;
author: AuthorFileType;
}; };
/** /**
@ -41,23 +39,33 @@ function guidePathToId(filePath: string): string {
return fileName.replace('.md', ''); return fileName.replace('.md', '');
} }
export async function getGuidesByAuthor(
authorId: string,
): Promise<GuideFileType[]> {
const allGuides = await getAllGuides();
return allGuides.filter((guide) => guide.author?.id === authorId);
}
/** /**
* Gets all the guides sorted by the publishing date * Gets all the guides sorted by the publishing date
* @returns Promisifed guide files * @returns Promisifed guide files
*/ */
export async function getAllGuides(): Promise<GuideFileType[]> { export async function getAllGuides(): Promise<GuideFileType[]> {
// @ts-ignore // @ts-ignore
const guides = await import.meta.glob<GuideFileType>( const guides = import.meta.glob<GuideFileType>('/src/data/guides/*.md', {
'/src/data/guides/*.md', eager: true,
{ });
eager: true,
}, const allAuthors = await getAllAuthors();
);
const guideFiles = Object.values(guides) as GuideFileType[]; const guideFiles = Object.values(guides) as GuideFileType[];
const enrichedGuides = guideFiles.map((guideFile) => ({ const enrichedGuides: GuideFileType[] = guideFiles.map((guideFile) => ({
...guideFile, ...guideFile,
id: guidePathToId(guideFile.file), id: guidePathToId(guideFile.file),
author: allAuthors.find(
(author) => author.id === guideFile.frontmatter.authorId,
)!,
})); }));
return enrichedGuides.sort( return enrichedGuides.sort(

@ -60,7 +60,7 @@ function roadmapPathToId(filePath: string): string {
* @returns string[] Array of roadmap IDs * @returns string[] Array of roadmap IDs
*/ */
export async function getRoadmapIds() { export async function getRoadmapIds() {
const roadmapFiles = await import.meta.glob<RoadmapFileType>( const roadmapFiles = import.meta.glob<RoadmapFileType>(
'/src/data/roadmaps/*/*.md', '/src/data/roadmaps/*/*.md',
{ {
eager: true, eager: true,
@ -79,14 +79,14 @@ export async function getRoadmapIds() {
export async function getRoadmapsByTag( export async function getRoadmapsByTag(
tag: string, tag: string,
): Promise<RoadmapFileType[]> { ): Promise<RoadmapFileType[]> {
const roadmapFilesMap = await import.meta.glob<RoadmapFileType>( const roadmapFilesMap = import.meta.glob<RoadmapFileType>(
'/src/data/roadmaps/*/*.md', '/src/data/roadmaps/*/*.md',
{ {
eager: true, eager: true,
}, },
); );
const roadmapFiles = Object.values(roadmapFilesMap); const roadmapFiles: RoadmapFileType[] = Object.values(roadmapFilesMap);
const filteredRoadmaps = roadmapFiles const filteredRoadmaps = roadmapFiles
.filter((roadmapFile) => roadmapFile.frontmatter.tags.includes(tag)) .filter((roadmapFile) => roadmapFile.frontmatter.tags.includes(tag))
.map((roadmapFile) => ({ .map((roadmapFile) => ({
@ -100,12 +100,10 @@ export async function getRoadmapsByTag(
} }
export async function getRoadmapById(id: string): Promise<RoadmapFileType> { export async function getRoadmapById(id: string): Promise<RoadmapFileType> {
const roadmapFilesMap = await import.meta.glob<RoadmapFileType>( const roadmapFilesMap: Record<string, RoadmapFileType> =
'/src/data/roadmaps/*/*.md', import.meta.glob<RoadmapFileType>('/src/data/roadmaps/*/*.md', {
{
eager: true, eager: true,
}, });
);
const roadmapFile = Object.values(roadmapFilesMap).find((roadmapFile) => { const roadmapFile = Object.values(roadmapFilesMap).find((roadmapFile) => {
return roadmapPathToId(roadmapFile.file) === id; return roadmapPathToId(roadmapFile.file) === id;

@ -1,4 +1,5 @@
import type { MarkdownFileType } from './file'; import type { MarkdownFileType } from './file';
import type {AuthorFileType} from "./author.ts";
export interface VideoFrontmatter { export interface VideoFrontmatter {
title: string; title: string;
@ -17,13 +18,14 @@ export interface VideoFrontmatter {
date: string; date: string;
sitemap: { sitemap: {
priority: number; priority: number;
changefreq: 'daily' | 'weekly' | 'monthly' | 'yealry'; changefreq: 'daily' | 'weekly' | 'monthly' | 'yearly';
}; };
tags: string[]; tags: string[];
} }
export type VideoFileType = MarkdownFileType<VideoFrontmatter> & { export type VideoFileType = MarkdownFileType<VideoFrontmatter> & {
id: string; id: string;
author: AuthorFileType;
}; };
/** /**
@ -43,12 +45,9 @@ function videoPathToId(filePath: string): string {
* @returns Promisifed video files * @returns Promisifed video files
*/ */
export async function getAllVideos(): Promise<VideoFileType[]> { export async function getAllVideos(): Promise<VideoFileType[]> {
const videos = await import.meta.glob<VideoFileType>( const videos = import.meta.glob<VideoFileType>('/src/data/videos/*.md', {
'/src/data/videos/*.md', eager: true,
{ });
eager: true,
}
);
const videoFiles = Object.values(videos); const videoFiles = Object.values(videos);
const enrichedVideos = videoFiles.map((videoFile) => ({ const enrichedVideos = videoFiles.map((videoFile) => ({
@ -59,6 +58,6 @@ export async function getAllVideos(): Promise<VideoFileType[]> {
return enrichedVideos.sort( return enrichedVideos.sort(
(a, b) => (a, b) =>
new Date(b.frontmatter.date).valueOf() - new Date(b.frontmatter.date).valueOf() -
new Date(a.frontmatter.date).valueOf() new Date(a.frontmatter.date).valueOf(),
); );
} }

@ -0,0 +1,110 @@
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import AstroIcon from '../../components/AstroIcon.astro';
import { getGuidesByAuthor } from '../../lib/guide';
import { getAllVideos } from '../../lib/video';
import GuideListItem from '../../components/GuideListItem.astro';
import { getAuthorById, getAuthorIds } from '../../lib/author';
interface Params extends Record<string, string | undefined> {}
export async function getStaticPaths() {
const authorIds = await getAuthorIds();
return authorIds.map((authorId) => ({
params: { authorId },
}));
}
const { authorId } = Astro.params;
const author = await getAuthorById(authorId);
const guides = await getGuidesByAuthor(authorId);
const videos = await getAllVideos();
---
<BaseLayout
permalink={`/author/${author.id}`}
title={`${author.frontmatter.name} - Author at roadmap.sh`}
briefTitle={author.frontmatter.name}
ogImageUrl={`https://roadmap.sh/${author.frontmatter.imageUrl}`}
description={`${author.frontmatter.name} has written ${guides.length} articles on roadmap.sh on a variety of topics.`}
noIndex={false}
>
<div class='container pt-4 pb-0 md:pb-16 md:pt-8'>
<div class=''>
<div class='mb-5 flex items-center gap-8 rounded-3xl py-0 md:py-8'>
<div>
<h1 class='text-2xl md:text-3xl font-bold'>{author.frontmatter.name}</h1>
<div
class='mt-1 mb-4 md:mt-4 md:mb-6 flex flex-col gap-3 text-gray-800 [&>p>a]:font-semibold [&>p>a]:underline leading-normal'
>
<author.Content />
</div>
<div class='flex items-center justify-between'>
<div class='flex items-center gap-1.5'>
{
author.frontmatter.social?.github && (
<a
href={author.frontmatter.social.github}
target='_blank'
class='text-gray-500 transition-colors hover:text-gray-800'
>
<AstroIcon icon='github' class='h-[20px]' />
</a>
)
}
{
author.frontmatter.social.twitter && (
<a
href={author.frontmatter.social.twitter}
target='_blank'
class='text-gray-500 transition-colors hover:text-gray-800'
>
<AstroIcon icon='twitter' class='h-[20px]' />
</a>
)
}
{
author.frontmatter.social.linkedin && (
<a
href={author.frontmatter.social.linkedin}
target='_blank'
class='text-gray-500 transition-colors hover:text-gray-800'
>
<AstroIcon icon='linkedin-2' class='h-[20px]' />
</a>
)
}
{
author.frontmatter.social.website && (
<a
href={author.frontmatter.social.website}
target='_blank'
class='text-gray-500 transition-colors hover:text-gray-800'
>
<AstroIcon icon='globe' class='h-[20px]' />
</a>
)
}
</div>
</div>
</div>
<div class='hidden flex-shrink-0 flex-col md:flex'>
<img
alt="Kamran Ahmed's profile picture"
class='block h-[175px] w-[175px] rounded-full bg-gray-100'
src={author.frontmatter.imageUrl}
/>
</div>
</div>
</div>
<div
class='rounded-t-xl bg-gradient-to-b from-gray-100 to-white px-3 py-2 md:px-6 md:py-3 [&>*:last-child]:border-b-0'
>
{guides.map((guide) => <GuideListItem guide={guide} />)}
</div>
</div>
</BaseLayout>
Loading…
Cancel
Save