Compare commits

..

399 Commits

Author SHA1 Message Date
Kamran Ahmed
68950ab2c9 Add helmet to thanks page 2021-09-09 22:57:34 +02:00
Kamran Ahmed
305d0a41ac Add thanks page 2021-09-09 22:41:57 +02:00
Kamran Ahmed
e43c21a01d Fix responsiveness issues 2021-09-09 22:32:12 +02:00
Kamran Ahmed
b6205af02c Change youtube banner color 2021-09-09 22:09:20 +02:00
Kamran Ahmed
6de2867d8a Disable carbon ads 2021-09-09 22:00:43 +02:00
Kamran Ahmed
13612323d7 Disable carbon ads 2021-09-09 21:55:53 +02:00
Kamran Ahmed
edd10470a7 Right align the carbon ad 2021-09-09 21:50:02 +02:00
Kamran Ahmed
d5b8d761d5 Update sponsor ads and carbon ad styling 2021-09-09 21:48:31 +02:00
Kamran Ahmed
9f7119694b Revert custom ad changes 2021-09-09 21:36:06 +02:00
Kamran Ahmed
8fbde17c22 Add carbon ads 2021-09-09 21:13:20 +02:00
Kamran Ahmed
e16947bd78 Enable custom ad 2021-09-09 16:38:30 +02:00
Kamran Ahmed
33af054161 Enable carbon ads 2021-09-08 23:33:08 +02:00
Kamran Ahmed
8913d5c5e4 Add youtube logo 2021-09-07 17:41:06 +02:00
Kamran Ahmed
0040d568b1 Add sponsor 2021-09-06 14:28:39 +02:00
Kamran Ahmed
706070e42a Add resources page 2021-09-05 22:52:18 +02:00
Kamran Ahmed
f79fb62ff9 Add sli, slo and sla guide 2021-09-05 22:38:37 +02:00
Kamran Ahmed
5c428540dc Add web vitals png 2021-09-05 22:24:38 +02:00
Kamran Ahmed
35ae0a74b3 Add keywords to frontend roadmap 2021-09-05 22:19:09 +02:00
Kamran Ahmed
a1606521d4 Fix missing title and description on video page 2021-09-05 22:13:49 +02:00
Kamran Ahmed
6545c8de36 Add youtube link to video page 2021-09-05 22:09:22 +02:00
Kamran Ahmed
0f713cbfd8 Add sticky banner for youtube 2021-09-05 21:58:44 +02:00
Kamran Ahmed
333894b75b Fix style for sponsor button 2021-09-05 21:19:51 +02:00
Kamran Ahmed
c73a500ffd Add back to roadmaps button 2021-09-05 21:17:51 +02:00
Kamran Ahmed
a489bc0fde Update dimmed button 2021-09-05 21:08:28 +02:00
Kamran Ahmed
09ef6bfbb0 Header logo fix 2021-09-05 20:55:22 +02:00
Kamran Ahmed
67d2f5cb57 Add support for environment variables 2021-09-05 20:38:08 +02:00
Kamran Ahmed
b28deab192 Update build workflow 2021-09-05 20:28:35 +02:00
Kamran Ahmed
290a73c8b0 Update dependencies 2021-09-05 20:25:48 +02:00
Kamran Ahmed
579d39e104 Merge branch 'master' of github.com:kamranahmedse/roadmap-next 2021-09-05 20:22:27 +02:00
Kamran Ahmed
e7c32958c9 Remove initial version 2021-09-05 20:22:21 +02:00
Kamran Ahmed
7c5d28b68b Add sponsor ad 2021-09-01 22:15:55 +02:00
Larah Armstrong
2f8c0c5748 Update what-is-internet.md (#190) 2021-02-02 09:36:38 +04:00
Kamran Ahmed
5e08af99b2 Update year 2021-01-08 14:41:49 +04:00
Yago Azedias
2882815313 Updating year to 2021 (#228) 2021-01-07 11:27:51 +04:00
Kamran Ahmed
e093f98a42 Add funding info 2020-11-23 01:19:34 +04:00
Kamran Ahmed
d3f8e0517b Add transport protocols video 2020-11-22 00:50:00 +04:00
Kamran Ahmed
efc874163b Add link to tcp/ip model video 2020-11-07 02:36:29 +04:00
Kamran Ahmed
3e8abbed13 Add sponsor and youtube link 2020-10-25 01:07:02 +04:00
Kamran Ahmed
244d336d8e Add link to osi model video 2020-10-24 23:34:57 +04:00
Kamran Ahmed
9d24b98f67 Add video for seal and freeze objects in JavaScript 2020-10-16 21:34:07 +04:00
Kamran Ahmed
007bd7feb0 Remove roadmaps from top nav 2020-10-16 15:17:03 +04:00
Kamran Ahmed
7619945028 Add http caching video link 2020-10-06 00:16:12 +04:00
Peter Thaleikis
3265f9729d Fixing missing 'mailto:' and broken link in Terms (#204)
* Fixing missing 'mailto:'

* Fixing broken link in Terms
2020-10-04 15:35:58 +04:00
Kamran Ahmed
4591ad2336 Add video for CDN 2020-09-26 22:01:22 +04:00
Kamran Ahmed
163e03f578 Update DBA roadmap 2020-09-21 23:42:07 +04:00
Kamran Ahmed
2215174c20 Update the DBA roadmap 2020-09-19 18:19:09 +04:00
Kamran Ahmed
aa52e08ac4 Add load balancers video link 2020-09-19 12:07:30 +04:00
lesovsky
96acb6c93e Add PostgreSQL DBA roadmap. 2020-09-09 08:36:15 +05:00
Kamran Ahmed
69ebd50a90 Add video link for dns records 2020-08-31 16:05:53 +05:00
Kamran Ahmed
e2eaf7d19c Add link to DNS video 2020-08-17 03:13:08 +04:00
Kamran Ahmed
da7ba5bf4c Add link to system design video 2020-08-09 09:18:44 +04:00
Kamran Ahmed
0d17cf145c Update URL for fetch api video 2020-08-02 22:20:27 +04:00
Kamran Ahmed
8a7f7a4a83 Update banner and new video link 2020-08-02 22:10:42 +04:00
Kamran Ahmed
7d3255576b Add video link for system design 2020-07-27 14:51:30 +04:00
Kamran Ahmed
97529cbf54 chore: trigger build 2020-07-26 13:31:58 +04:00
Kamran Ahmed
52af178a19 Update guide URL and add images 2020-07-26 12:19:16 +04:00
Ebrahim Bharmal
f0425fd964 Adding guide for forward and reverse proxy servers (#185)
* Add files via upload

* Update forward&reverse_proxy.md

* Update forward&reverse_proxy.md

* Update forward&reverse_proxy.md

Checking links

* Update forward&reverse_proxy.md

Updated all links. Now images show up properly

* Update forward&reverse_proxy.md

Updated headings. Made changes to the format.

* Update forward&reverse_proxy.md

Changes made againnnnnn

* Update forward&reverse_proxy.md

Updated structure. Added more content.

* Update forward&reverse_proxy.md

* Update forward&reverse_proxy.md

Added table of contents

* Update forward&reverse_proxy.md

Corrected some lines

* Update forward&reverse_proxy.md

Updated final version: Fixed spelling mistakes and errors

* Added picture of ebrahimbharmal007

Contributing to guides: forward&reverse_proxy.md

* Updated authors.json: add author ebrahimbharmal007

Added ebrahimbharmal007 in authors.json for submitting guide forward&reverse_proxy.md

* Updated guides.json

Added meta data for guide forward&reverse_proxy.md by ebrahimbharmal007
2020-07-26 12:06:29 +04:00
Kamran Ahmed
570d6a04b1 Add promises video link 2020-07-21 01:02:45 +04:00
Kamran Ahmed
1e677183aa Add react roadmap 2020-07-18 15:59:04 +04:00
Kamran Ahmed
14a29b4634 Add react map files 2020-07-18 04:13:19 +04:00
Kamran Ahmed
bc66a805e3 Add react roadmap 2020-07-18 04:12:33 +04:00
Kamran Ahmed
f6c10d7344 Fix invalid links for the videos 2020-07-18 00:43:47 +04:00
Kamran Ahmed
4e96943374 Add links to podcast and watch in footer 2020-07-17 15:44:47 +04:00
Kamran Ahmed
1235459d7a Add post on ci/cd 2020-07-17 15:39:48 +04:00
Kamran Ahmed
0d35fe0364 Add webstorm project history image 2020-07-17 15:26:57 +04:00
Kamran Ahmed
76d6fab581 Add guide on single sign on 2020-07-17 15:19:19 +04:00
Kamran Ahmed
da39147539 Add youtube videos page 2020-07-17 15:14:28 +04:00
lincarters
9e230a01a2 Update resources.md
Spelling fix
2020-07-16 14:58:47 +04:00
Kamran Ahmed
4c3452926a Fix image URL for oauth 2020-07-02 16:48:30 +04:00
Kamran Ahmed
b36c5b3c26 Add oauth post 2020-07-02 15:31:04 +04:00
Kamran Ahmed
95fe79a0f1 Add podcasts menu 2020-06-22 01:58:52 +04:00
Kamran Ahmed
850a9ffc9d Add podcasts page 2020-06-22 01:52:29 +04:00
Kamran Ahmed
2b8d18d880 Refactor deployment action 2020-06-22 00:25:22 +04:00
Kamran Ahmed
9b551a69a7 Fix deployment step failing 2020-06-22 00:20:21 +04:00
Kamran Ahmed
cdb9201b2f Refactor build steps 2020-06-22 00:14:16 +04:00
Kamran Ahmed
ab15d91614 Add deployment github action 2020-06-22 00:06:44 +04:00
Kamran Ahmed
9d2fdfa7cf Add support for environment variables 2020-06-21 23:38:38 +04:00
Kamran Ahmed
bcad685e27 Update contribution guides 2020-06-21 23:01:47 +04:00
Kamran Ahmed
74ae339fe1 Add JWT Authentication guide 2020-06-20 23:16:04 +04:00
Kamran Ahmed
5811fd8832 feat: add png for android roadmap 2020-06-11 19:58:34 +04:00
Kamran Ahmed
6c710a92c1 Add token authentication guide 2020-06-04 12:41:21 +04:00
Kamran Ahmed
51f068085d Update android roadmap 2020-05-30 02:46:13 +04:00
Kamran Ahmed
1795bc1495 Update twitter URL 2020-05-26 23:00:41 +04:00
Kamran Ahmed
d4ef930187 Add community badge 2020-05-26 22:39:09 +04:00
Kamran Ahmed
54fae335c2 Update twitter URL 2020-05-26 18:57:32 +04:00
Kamran Ahmed
0f886e9def Create SVG for android roadmap 2020-05-26 14:27:42 +04:00
Kamran Ahmed
3f299cdd8b Create SVG for android roadmap 2020-05-26 14:16:53 +04:00
Kamran Ahmed
7fccd6b399 Fix typos and minor alignment fixes 2020-05-26 13:28:07 +04:00
Kamran Ahmed
f75512e96a Add android developer roadmap 2020-05-26 13:23:06 +04:00
Kamran Ahmed
32ff9a700b Add android developer roadmap 2020-05-26 04:11:58 +04:00
Kamran Ahmed
6976202171 Replace homepage with roadmaps page 2020-05-25 22:34:16 +04:00
Kamran Ahmed
cf1cca7cb3 Add guide on session based authentication 2020-05-25 22:29:52 +04:00
Kamran Ahmed
2236c3f93c Add basic authentication guide 2020-05-19 01:22:07 +04:00
Kamran Ahmed
4f067504a2 Add character encodings post 2020-05-14 02:52:15 +04:00
Kamran Ahmed
42747f4f97 Add unfamiliar codebase post 2020-05-04 23:32:17 +04:00
Kamran Ahmed
1d952f75f8 Add unfamiliar codebase post 2020-05-04 23:29:26 +04:00
Peter Thaleikis
9e61ef5dd1 Add guide "Why “build it and they will come” alone won’t work anymore" 2020-05-04 23:09:40 +04:00
Kamran Ahmed
c7770cc64c Add dhcp illustration 2020-04-28 13:16:11 +04:00
Kamran Ahmed
af7e25dc92 Fix github buttons width 2020-04-28 11:13:22 +04:00
Kamran Ahmed
cf3365e778 feat: add carbon 2020-04-24 22:45:23 +04:00
Kamran Ahmed
bd69872059 feat: add guide SSL/TLS/HTTPS/SSH 2020-04-24 20:45:32 +04:00
Jefferson Ye
746ee3d548 Small grammar fix, "ambition" to "ambitious" 2020-04-22 13:37:48 +04:00
Kamran Ahmed
73c55a0eaa Add scaling databases post 2020-04-03 12:01:15 +04:00
Kamran Ahmed
299d0f3ada Add guide for asymptotic notation 2020-04-03 11:41:12 +04:00
Kamran Ahmed
98097f939a Update youtube URL 2020-03-30 01:51:09 +04:00
Kamran Ahmed
f4904da3f8 Update github link in page nav 2020-03-28 20:35:58 +04:00
Kamran Ahmed
465c00b4d5 Update dependencies and add github link in nav 2020-03-28 20:23:17 +04:00
Myles Webster
69c54e5dfe fix incorrect link for resource in FE dev roadmap 2020-03-25 18:29:44 +04:00
Kamran Ahmed
6f4898c216 Add illustrations for some topics 2020-03-23 22:33:39 +04:00
Kamran Ahmed
b8cc07c29e Update channel link 2020-03-15 16:13:36 +04:00
Kamran Ahmed
eae0ad3ecb Update alignment for share links 2020-03-14 12:49:26 +04:00
Kamran Ahmed
56bf52e641 Add hackernews share url 2020-03-14 12:48:11 +04:00
Kamran Ahmed
689f24e0f1 Add random numbers guide 2020-03-14 12:37:31 +04:00
Kamran Ahmed
63d66b3f4e Add big-o-notation guide 2020-03-14 02:40:57 +04:00
Kamran Ahmed
4930c00f78 Update roadmap pdfs 2020-03-14 01:54:46 +04:00
Kamran Ahmed
5745fc56bf Update pdfs for the roadmaps 2020-03-14 01:45:05 +04:00
Kamran Ahmed
55d5ced587 Type updates and banner change 2020-03-14 01:37:27 +04:00
Kamran Ahmed
018be76895 Add youtube banner 2020-03-14 01:02:04 +04:00
Kamran Ahmed
b268106684 Add youtube banner 2020-03-14 01:00:06 +04:00
Kamran Ahmed
56e2108be2 Add resources link in SSG 2020-03-03 00:18:32 +04:00
Kamran Ahmed
9dfbceda7c Update forntend resources 2020-03-03 00:10:33 +04:00
Kamran Ahmed
c698265f42 Add frontend resources 2020-03-03 00:06:25 +04:00
Kamran Ahmed
752d4614b8 Add resources to frontend 2020-03-02 10:52:48 +04:00
Kamran Ahmed
d73e08f8f6 Add resources setup 2020-03-01 10:27:15 +04:00
Kamran Ahmed
cf648924cf Add resources pages and new guide 2020-02-29 17:49:04 +04:00
Kamran Ahmed
2d15290566 Add menu items for resources and project ideas 2020-02-28 19:58:29 +04:00
Kamran Ahmed
06dd1934f3 Fix typo 2020-02-27 10:46:06 +04:00
Christoph Geschwind
316ada1259 Update levels-of-seniority.md
Fixes a tiny typo, at least I think it does.

Thanks for the great article!
2020-02-27 10:46:06 +04:00
Sohail Ahmad
30d2f15433 Fix typo ('compabitility' -> 'compatibility') 2020-02-26 20:27:31 +04:00
Kamran Ahmed
4ac1319d8d Update sponsor banner text 2020-02-22 21:44:05 +04:00
Andrew Petro
4e924981c1 fix: diction and typo ("its", "simplest") 2020-02-11 12:50:29 +04:00
Andrew Petro
fdf3fd050b fix: use "its" rather than "it's" when appropriate
Use "its" for the possessive, rather than "it's" (contraction of for "it is").
2020-02-11 12:50:29 +04:00
Will 保哥
79afd0a6a8 Update history-of-javascript.md
Add a space in a paragraph.
2020-02-11 12:47:13 +04:00
Will 保哥
03e35ee928 Update history-of-javascript.md
Typos: ECMASript -> ECMAScript
2020-02-11 12:44:15 +04:00
Curtis Gibby
eaaedb8034 Update name of Dunning–Kruger effect 2020-02-07 22:46:13 +04:00
Kamran Ahmed
84e87a501e Add do logo 2020-02-04 02:00:27 +04:00
Kamran Ahmed
8fca669787 Add do logo 2020-02-04 01:57:27 +04:00
Kamran Ahmed
3c1d41119f Add sponsor information 2020-02-01 18:05:57 +04:00
Kamran Ahmed
495fd37eae Add sponsor information 2020-02-01 17:55:54 +04:00
Kamran Ahmed
4cfeb1c372 Add pdfs for roadmaps 2020-02-01 17:23:53 +04:00
Kamran Ahmed
91a47faec0 Add sponsor information 2020-02-01 17:08:34 +04:00
Kamran Ahmed
8c03aedea1 Add sponsor banner 2020-02-01 13:33:14 +05:00
Kamran Ahmed
9a515f85c1 Hide sponsors nav item on mobile 2020-02-01 08:07:42 +05:00
Kamran Ahmed
0a2468aad2 Make frontend roadmap summary 2020-01-29 13:53:39 +05:00
Kamran Ahmed
fc2eb36d58 Resolve merge conflicts 2020-01-29 12:49:49 +05:00
Kamran Ahmed
3c5ea2131d Add detailed version for frontend roadmap 2020-01-29 12:48:18 +05:00
Kamran Ahmed
75e1f67ee8 Use on heading per page 2020-01-29 11:28:20 +05:00
Kamran Ahmed
b40894cfdc SEO optimization through titles/descriptions 2020-01-29 11:14:34 +05:00
Kamran Ahmed
4fb2e1f46d Fix SEO titles and keywords 2020-01-29 10:42:52 +05:00
Kamran Ahmed
8eccfd22e3 Update copy 2020-01-29 09:43:24 +05:00
Kamran Ahmed
d84800fcaf feat: detailed roadmap preparation 2020-01-28 17:48:22 +05:00
Kamran Ahmed
bb3260f4b7 Update contribution guidelines 2020-01-27 13:09:16 +05:00
Kamran Ahmed
9a2e1fd673 Add contribution guide for writing roadmap 2020-01-27 12:41:02 +05:00
Kamran Ahmed
3f599fab35 Remove gads 2020-01-22 12:13:25 +04:00
Kamran Ahmed
cdc710123f Add codefund 2020-01-22 12:11:24 +04:00
Kamran Ahmed
bb43c8eba6 Update sponsors info 2020-01-21 10:42:34 +04:00
Kamran Ahmed
c01d595546 Update sponsors info 2020-01-21 00:27:46 +04:00
Kamran Ahmed
77a66fd25d Add sponsors page 2020-01-21 00:20:25 +04:00
Kamran Ahmed
a93ac86766 Update sitemap 2020-01-20 11:24:36 +04:00
Kamran Ahmed
4044dbea91 Update sitemap path 2020-01-20 11:24:02 +04:00
Kamran Ahmed
3fc9ffe8b4 Update copy on sponsors page 2020-01-20 11:17:37 +04:00
Kamran Ahmed
880475f6de Add sponsors page 2020-01-20 10:58:39 +04:00
Kamran Ahmed
a26945288b Rename storage directory 2020-01-18 22:47:48 +04:00
Kamran Ahmed
b97ae52a1b Add PDF for devops roadmap 2020-01-18 16:56:27 +04:00
Kamran Ahmed
76ddeeedb2 Add devops roadmap 2020 update 2020-01-18 16:30:03 +04:00
Kamran Ahmed
00b7fe6e7f fix: electro misspelling and color for legend 2020-01-18 11:00:51 +04:00
Kamran Ahmed
c43442f127 Merge branch 'master' of github.com:kamranahmedse/roadmap.sh 2020-01-18 10:45:12 +04:00
Kamran Ahmed
68c62d218d feat: update 2020-01-18 10:44:58 +04:00
Kamran Ahmed
47b10a1a1a Fix broken logo in readme 2020-01-18 01:12:41 +04:00
Kamran Ahmed
1fd135d1c1 Move static to public and update paths 2020-01-18 01:08:47 +04:00
Kamran Ahmed
61bdc80f5a Update dependencies 2020-01-18 01:05:13 +04:00
Kamran Ahmed
4fbefd5ae9 Update site meta and title update for post 2020-01-18 00:56:49 +04:00
Jesse Li
835476ed31 Update PULL_REQUEST_TEMPLATE.md 2020-01-17 21:39:27 +04:00
Jesse Li
83745ae1b4 Add Guide: BitTorrent client 2020-01-17 21:39:27 +04:00
Kamran Ahmed
9465cfb5c2 feat: update author meta 2020-01-17 19:32:50 +04:00
Kamran Ahmed
4edd398770 chore: add contribution docs for writing guides 2020-01-17 19:29:04 +04:00
Kamran Ahmed
21b3b7cbdf fix: invalid canonicalization 2020-01-17 19:18:47 +04:00
Kamran Ahmed
ae6763bf83 Fix search engines section in backend 2020-01-12 10:31:22 +04:00
Kamran Ahmed
be5a61b697 Fix typo in backend roadmap 2020-01-12 00:44:15 +04:00
Kamran Ahmed
8e25dca636 Update PDF files and add 2020 version 2020-01-12 00:09:33 +04:00
Kamran Ahmed
b91d404f17 Merge branch 'master' of github.com:kamranahmedse/roadmap.sh 2020-01-10 18:55:00 +04:00
Kamran Ahmed
80f2cb8cbc Fix typos in frontend roadmap 2020-01-10 18:54:47 +04:00
Kamran Ahmed
2dc3d4fd24 Fix typos in frontend 2020-01-10 18:52:16 +04:00
Joshua Mamawag
2432ff9fd4 Fix typos and punctuations 2020-01-10 17:49:42 +04:00
Kamran Ahmed
8f1f8846c9 Update badges 2020-01-04 18:34:19 +04:00
Kamran Ahmed
7dac8665a0 Update badges 2020-01-04 18:33:21 +04:00
Kamran Ahmed
f0181ff08f Add PDFs for roadmaps 2020-01-04 18:01:21 +04:00
Kamran Ahmed
0ad95c2dd0 Update links 2020-01-04 17:57:50 +04:00
Kamran Ahmed
d184e93519 Add PDF for frontend roadmap 2020-01-04 17:41:03 +04:00
Kamran Ahmed
4ef31700a5 Update frontend and intro maps for 2020 2020-01-04 17:39:39 +04:00
Kamran Ahmed
087f4e5c25 Add license and github templates 2020-01-04 17:38:43 +04:00
Kamran Ahmed
c5ae26458a Update roadmaps for 2020 2020-01-04 17:35:41 +04:00
Kamran Ahmed
0c6de5d89b Add contribution guide 2020-01-02 09:59:41 +04:00
Kamran Ahmed
124d113162 Update sitemap and roadmaps 2020-01-02 09:54:52 +04:00
Kamran Ahmed
c88b0f3b1a Update sitemap, roadmap meta 2020-01-02 09:49:01 +04:00
Kamran Ahmed
06d72599d9 Resolve merge conflicts 2020-01-02 09:42:48 +04:00
Kamran Ahmed
eb9cd6cdcc Update dependencies 2020-01-02 09:40:55 +04:00
Kamran Ahmed
c7589b8325 Update summary pages for roadmaps 2019-12-06 18:18:33 +04:00
Kamran Ahmed
4c07ac509b Add SVG for the logo 2019-12-06 15:47:40 +04:00
Kamran Ahmed
1240b6b1bc Fix typos in guide 2019-12-04 01:02:58 +04:00
Kamran Ahmed
ad05c49570 Fix - Breaking build 2019-12-03 18:09:47 +04:00
Kamran Ahmed
c01a854a5a Fix - Duplicated meta tags on pages 2019-12-03 17:54:34 +04:00
Kamran Ahmed
7b1dde1d62 Fix Typos in Guide 2019-12-03 17:34:20 +04:00
Kamran Ahmed
56b0275b06 Update the conclusion on guide 2019-12-03 17:22:19 +04:00
Kamran Ahmed
7a0d784d81 Update twitter card image 2019-12-03 17:03:12 +04:00
Kamran Ahmed
2c9eb1f9ee Make twitter card logo square 2019-12-03 16:58:58 +04:00
Kamran Ahmed
e4ca1c9598 Add guide: Levels of Seniority 2019-12-03 16:40:31 +04:00
Kamran Ahmed
2b8e06d651 Add senior section 2019-12-03 02:55:56 +04:00
Kamran Ahmed
56088a838c Add section for mid-level developers 2019-12-03 01:30:00 +04:00
Kamran Ahmed
542d82c2dc Developer seniority junior section 2019-12-03 00:12:51 +04:00
Kamran Ahmed
980322bae0 Add Guide: Developer seniority 2019-12-02 17:08:49 +04:00
Kamran Ahmed
56fbe9a685 Add Guide: history of JavaScript 2019-12-02 13:06:35 +04:00
Kamran Ahmed
6939240d59 Add junior frontend landscape 2019-12-02 12:20:06 +04:00
Kamran Ahmed
4caaee3da5 Update badges 2019-12-02 03:31:25 +04:00
Kamran Ahmed
e829af3e62 Update summary 2019-12-02 02:13:21 +04:00
Kamran Ahmed
7ba0fa9004 Update meta 2019-12-02 02:12:26 +04:00
Kamran Ahmed
74433cd0d3 Sticky sidebar 2019-12-02 02:11:49 +04:00
Kamran Ahmed
dec3e992b3 Update frontend roadmap summary 2019-12-02 01:58:31 +04:00
Kamran Ahmed
7a4c27460f Add summary details for frontend developer 2019-12-02 00:28:10 +04:00
Kamran Ahmed
5553b411eb Add summary 2019-12-02 00:00:57 +04:00
Kamran Ahmed
98cc968ed1 Add roadmap summary for frontend 2019-12-01 23:51:23 +04:00
Kamran Ahmed
3de37468a6 Render page markdown 2019-12-01 17:06:53 +04:00
Kamran Ahmed
3364eae0a6 Change sitemap priority for hidden pages 2019-12-01 16:17:29 +04:00
Kamran Ahmed
a06eaec5d4 Add summary pages to landscape 2019-12-01 16:16:45 +04:00
Kamran Ahmed
10e433f538 Do not display hidden pages 2019-12-01 15:49:13 +04:00
Kamran Ahmed
129deed6a9 Roadmap author and contributors page 2019-12-01 15:46:13 +04:00
Kamran Ahmed
ce35a8112f Remove utm params from share URLs 2019-12-01 15:11:28 +04:00
Kamran Ahmed
35f6070133 Relevant page loading on detail page 2019-12-01 15:01:22 +04:00
Kamran Ahmed
629f1058f2 Make mobile sidebar responsive 2019-11-30 18:12:07 +04:00
Kamran Ahmed
199310df93 Add share icons on roadmap detail page 2019-11-30 17:15:56 +04:00
Kamran Ahmed
0d45fcbf79 Add share icons to roadmap header 2019-11-30 17:07:50 +04:00
Kamran Ahmed
47cbcde5dc Add detailed roadmap 2019-11-30 14:33:22 +04:00
Kamran Ahmed
5b12eb9e02 Split roadmap summaries and detailed roadmap 2019-11-30 14:27:37 +04:00
Kamran Ahmed
6632b46d98 Fix - Guide having space on top 2019-11-30 14:27:21 +04:00
Kamran Ahmed
25e009a63f Update roadmaps summaries 2019-11-30 14:26:03 +04:00
Kamran Ahmed
9ae7eed1e3 Remove static images 2019-11-30 14:25:31 +04:00
Kamran Ahmed
8db62cb19f Update badges 2019-11-30 11:21:14 +04:00
Kamran Ahmed
d1a991b18c Add badges 2019-11-30 11:14:42 +04:00
Kamran Ahmed
8107e008ff Overflowing scroll on page 2019-11-30 10:28:37 +04:00
Kamran Ahmed
944858bbb1 Make upcoming badge take to signup 2019-11-30 10:27:39 +04:00
Kamran Ahmed
b864c60ea3 Upcoming roadmap page 2019-11-30 10:00:44 +04:00
Kamran Ahmed
618b55f601 Split roadmap header to separate component 2019-11-30 09:06:06 +04:00
Kamran Ahmed
b5c65b408b Update meta script 2019-11-30 00:43:29 +04:00
Kamran Ahmed
21f2ef80ba Upcoming roadmap UI 2019-11-30 00:20:24 +04:00
Kamran Ahmed
ebd351e133 Refactor markdown rendering 2019-11-29 18:36:49 +04:00
Kamran Ahmed
77dab81b92 Add padding around container 2019-11-29 18:13:19 +04:00
Kamran Ahmed
0350da2929 Split markdown rendering 2019-11-29 18:13:07 +04:00
Kamran Ahmed
59c07c9000 Minor update 2019-11-29 11:51:43 +04:00
Kamran Ahmed
79ab31dec7 Update sitemap generation for roadmap pages 2019-11-29 11:49:50 +04:00
Kamran Ahmed
16983cb950 Update path-map generation 2019-11-29 11:23:48 +04:00
Mazhar Zandsalimi
e29fe52cb1 minor modification: max-age=3600 means 60 minutes 2019-11-29 10:48:40 +04:00
Kamran Ahmed
7921acb666 Add roadmaps meta generator 2019-11-28 00:19:03 +04:00
Kamran Ahmed
b53f8c982c Update pathmap generation for roadmap routes 2019-11-27 20:53:29 +04:00
Kamran Ahmed
0b72a07147 Add roadmap pathmap generator 2019-11-25 21:00:37 +04:00
Konstantinos Psychas
5155a0c358 Update design-patterns-for-humans.md
A typo that may cause confusion.
2019-11-24 11:26:49 +04:00
Kamran Ahmed
bd5663ab26 Add roadmap text 2019-11-23 16:30:48 +04:00
Kamran Ahmed
af3ccd5bb5 Fix broken build 2019-11-21 18:22:57 +04:00
B3nnyL
035eaa47e8 [fix]canonical url and og:url 2019-11-21 11:57:21 +04:00
Pat Laundy
3541d4e717 Adding missed word in opening paragraph 2019-11-19 09:33:25 +04:00
Kamran Ahmed
e8dcfe97f2 Fix - Subscription form throws warning 2019-11-16 16:16:50 +04:00
Kamran Ahmed
8f3307e53e Update sitemap and build 2019-11-16 16:15:05 +04:00
Kamran Ahmed
dcc825416d Push dev configuration 2019-11-16 16:13:37 +04:00
Kamran Ahmed
f8fcb8d600 Update build script 2019-11-16 16:12:18 +04:00
Kamran Ahmed
40919dec14 Add configuration and build changes 2019-11-16 16:11:08 +04:00
Kamran Ahmed
f3592155bf Add build check for .env file 2019-11-16 15:35:37 +04:00
Kamran Ahmed
927ee73be7 Add dotenv file loading 2019-11-16 15:21:40 +04:00
Kamran Ahmed
4f81d5374e Fix - Analytics not working 2019-11-16 15:07:10 +04:00
Kamran Ahmed
e95fd69886 Update subscribe button in top nav 2019-11-16 14:18:43 +04:00
Kamran Ahmed
11d9da5afb Update FAQ page 2019-11-16 14:06:31 +04:00
Kamran Ahmed
cea8abc5ef Update build script 2019-11-16 14:02:16 +04:00
Kamran Ahmed
7169d3bb8f Add FAQ page in top nav 2019-11-16 13:54:36 +04:00
Kamran Ahmed
ae9c1c4992 Add about page 2019-11-16 13:51:10 +04:00
Kamran Ahmed
58e560af7d Do not send analytics for dev mode 2019-11-16 13:50:30 +04:00
Kamran Ahmed
09fa166f56 Delete .nojekyll 2019-11-15 02:12:02 +04:00
Kamran Ahmed
6ed7d9c25f Create .nojekyll 2019-11-15 02:11:24 +04:00
Kamran Ahmed
e59fc5e4e9 Update canonical URL 2019-11-15 02:09:54 +04:00
Kamran Ahmed
f5da05c3ec Update canonical URL 2019-11-15 02:08:45 +04:00
Kamran Ahmed
07b200b878 Update readme.md 2019-11-14 22:31:12 +04:00
Kamran Ahmed
ccca782f25 Update readme 2019-11-14 22:30:49 +04:00
Kamran Ahmed
77d9846d9b Update readme 2019-11-14 22:22:04 +04:00
Kamran Ahmed
8da175e9d8 Update readme 2019-11-14 21:32:28 +04:00
Kamran Ahmed
467634889b Update repository URL 2019-11-14 21:29:30 +04:00
Kamran Ahmed
b46b425b41 Fix twitter share URL issue 2019-11-14 21:26:01 +04:00
Kamran Ahmed
9e23439f0c Add sitemap generation and remove extra files 2019-11-14 21:21:56 +04:00
Kamran Ahmed
c6db625e35 Update license 2019-11-14 12:09:51 +04:00
Kamran Ahmed
672245e4e4 Fix invalid URL being generated 2019-11-13 23:44:45 +04:00
Kamran Ahmed
e4ce3475c6 Update repository URLs 2019-11-13 23:38:29 +04:00
Kamran Ahmed
d15b97db73 Update bundle application 2019-11-13 23:29:52 +04:00
Kamran Ahmed
8f040e5e8a Add gh-pages deployment 2019-11-13 23:13:45 +04:00
Kamran Ahmed
888800d2a0 Update contribution docs 2019-11-13 23:07:29 +04:00
Kamran Ahmed
51b2c70586 Restructure and update imports 2019-11-13 23:06:07 +04:00
Kamran Ahmed
5b4cc86f61 Restructure and update readme 2019-11-13 22:59:27 +04:00
Kamran Ahmed
9952ee5805 Resolve merge conflicts 2019-11-13 22:48:43 +04:00
Stéphane Klein
dacbf09f55 Remove JSCS (deprecated) and add StandardJS linter (#605) 2019-07-10 10:26:35 +04:00
Kamran Ahmed
a16787ab58 Remove myself from github sponsors 2019-07-07 15:59:19 +04:00
Rahul Madhav Upakare
7d45c8e462 Corrected language name for Go programming language (#601) 2019-07-05 18:05:06 +04:00
Kamran Ahmed
796bde76c9 Update copy 2019-07-01 13:33:06 +04:00
Kamran Ahmed
22d5622e1e Add funding.yml 2019-05-23 16:30:44 +04:00
Eric Jeker
2312fdd608 Duplicated word in the CSS Architecture comment box. Removed 'push'. 2019-05-17 16:59:23 +04:00
Kamran Ahmed
bc2ecea03b Update license 2019-05-13 02:47:20 +04:00
Kamran Ahmed
84a551f906 Fix transparency of roadmaps 2019-05-06 13:04:27 +04:00
Kamran Ahmed
9fab5c7134 Update devops map 2019-05-06 12:21:47 +04:00
Kamran Ahmed
c61f4a845d Fix some typos and update banner 2019-05-06 12:07:28 +04:00
Kamran Ahmed
025753b279 Fix spelling mistake 2019-05-06 11:17:24 +04:00
Kamran Ahmed
6b9901db28 Update the banner 2019-05-05 01:18:22 +04:00
Kamran Ahmed
34f0e483ec Update repo banneer 2019-05-05 00:44:15 +04:00
Kamran Ahmed
0ae9bc0e3e Update repo banner 2019-05-05 00:40:46 +04:00
Kamran Ahmed
3f17f60daf Update headeer 2019-05-05 00:30:36 +04:00
Kamran Ahmed
7f2acba352 Add sponsor 2019-03-18 00:44:13 +04:00
johnoct
907fb9915f fix the cut off names teamcity, LXC, and puppet 2019-03-17 10:06:19 +04:00
Kamran Ahmed
fd2e64ec50 Update sponsors 2019-03-12 10:29:23 +04:00
Kamran Ahmed
3fd5b9e744 Update sponsor text 2019-02-06 10:11:16 +04:00
Kamran Ahmed
edff9156ff Update sponsor link 2019-02-05 15:20:32 +04:00
Kamran Ahmed
e1c89585e9 Add sponsor link 2019-02-05 15:05:15 +04:00
Kamran Ahmed
abaa839b26 Fix transparency for backend roadmap 2019-01-26 14:55:41 +04:00
Kamran Ahmed
1bc7384929 Minor markdown change 2019-01-04 10:10:55 +04:00
Kamran Ahmed
6a148295f7 Update sponsors section 2019-01-04 10:10:30 +04:00
Kamran Ahmed
ea25f2d99b Update readme 2019-01-02 21:48:30 +04:00
Kamran Ahmed
08303c0623 Update badge 2019-01-01 14:26:33 +04:00
Kamran Ahmed
f18f9fb5b3 Fix tweet URL 2018-12-30 21:10:46 +04:00
Kamran Ahmed
dfc07e0753 Remove emojis 2018-12-29 23:32:52 +04:00
Kamran Ahmed
64a19fdc3c Update badge 2018-12-29 23:23:39 +04:00
Kamran Ahmed
1b3e8712ff Rearrange badges 2018-12-29 22:51:56 +04:00
Kamran Ahmed
f242c6e358 Update badges and intro section 2018-12-29 22:51:10 +04:00
Kamran Ahmed
7e2121bed9 Merge branch 'master' of github.com:kamranahmedse/developer-roadmap 2018-12-29 22:48:26 +04:00
Kamran Ahmed
bb80ceb7ba Update intro map 2018-12-29 22:48:19 +04:00
Kamran Ahmed
25dfb28368 Update badge 2018-12-29 22:32:58 +04:00
Kamran Ahmed
a1c75bb9f8 Update badges 2018-12-29 22:32:37 +04:00
Kamran Ahmed
efdb628120 Update badges 2018-12-29 22:31:20 +04:00
Kamran Ahmed
ac23dddeb9 Update header 2018-12-29 21:44:43 +04:00
Kamran Ahmed
b208eaa1bd Update frontend roadmap for 2019 2018-12-29 20:39:20 +04:00
Kamran Ahmed
8ebf97277c Add updated frontend roadmap 2018-12-29 20:37:25 +04:00
Kamran Ahmed
928d79e3fb Update frontend roadmap image 2018-12-29 17:27:52 +04:00
Kamran Ahmed
9b95218eb8 Update frontend roadmap image 2018-12-29 17:20:02 +04:00
Kamran Ahmed
8bcdd84f0f Update frontend developer roadmap 2018-12-29 17:17:46 +04:00
Asad Mansoor
67a72aab11 added container orchestration to devops roadmap (#518)
* added container orchestration to devops roadmap

* Added kubernetes as preferred
2018-11-29 10:25:13 +04:00
Kamran Ahmed
771f3a9cb7 Merge branch 'bekicot-fetch-api-for-frontend' 2018-10-16 12:19:23 +04:00
Kamran Ahmed
38b6b34437 Resolve merge conflicts 2018-10-16 12:19:10 +04:00
Kamran Ahmed
548dfd85e7 Add Fetch API 2018-10-16 12:14:43 +04:00
Kamran Ahmed
971d23c43a Contribution docs update 2018-10-16 12:11:07 +04:00
Kamran Ahmed
3aac8de849 Add contribution docs 2018-10-16 12:00:49 +04:00
Ahmad Awais ⚡️
8d605735b2 👌 IMPROVE: Contribution Docs + Fix Frontend RoadMap (#498)
* 📦 NEW: No auto formatting for JSON in VSCode

* 👌 IMPROVE: lingo for several libraries/software

* 👌 IMPROVE: alt text for Web Developer Roadmap Introduction

* 👌 IMPROVE: alt text for Frontend Roadmap

* 👌 IMPROVE: alt text for Back-end Roadmap

* 👌 IMPROVE: alt text for DevOps Roadmap

*  📖 DOC: make contribution fun again with more details

* 🐛 FIX: names of several libraries/software
2018-10-16 11:21:44 +04:00
Yana Agun Siswanto
7debdb90c1 frontend-map.json: add Fetch API as recomendation
Fetch API should be added instead of XMLHttpRequest(XHR) API
as fetch uses promises which enables a simpler and cleaner API.
However, understanding both Fetch/XHR is required for frontend.

Closes #475
2018-10-16 05:28:00 +07:00
Andre Christoga Pramaditya Sion
f6f5c821b3 Emoji for both genders (#502)
Because the tech isn't for males only.
2018-10-12 00:48:08 +04:00
Kamran Ahmed
227e08b7c4 Don't need coffee 2018-09-09 22:18:27 +04:00
Kamran Ahmed
16651606fb Add badge 2018-09-08 20:11:23 +04:00
Kamran Ahmed
0ea67f695d Remove sponsor 2018-07-02 14:44:32 +04:00
Kamran Ahmed
6c4386ed7d Update license 2018-06-09 17:56:23 +04:00
Kamran Ahmed
e65ba9365b Add license 2018-06-09 17:53:56 +04:00
Kamran Ahmed
e5843568dd Add License 2018-06-09 17:52:57 +04:00
Kamran Ahmed
7968151c44 Update backend map 2018-06-09 04:35:03 +04:00
Kamran Ahmed
9f0753f098 Add devops map 2018-06-09 04:24:11 +04:00
Kamran Ahmed
98d0aa5103 Update backend roadmap 2018-06-08 18:14:13 +04:00
Kamran Ahmed
c1706e2c18 Remove banner 2018-06-06 21:28:24 +04:00
Kamran Ahmed
84e74096b7 Update readme 2018-05-05 23:02:07 +02:00
Kamran Ahmed
3d96fdf1df Update weekly 2018-04-08 00:24:35 +02:00
Kamran Ahmed
a157605b2b Update readme.md 2018-04-07 23:34:34 +02:00
Kamran Ahmed
ec83830577 Update readme 2018-04-07 02:49:19 +02:00
Kamran Ahmed
6babeb3f21 Add esguy link 2018-04-07 02:48:03 +02:00
Kamran Ahmed
0b9754c9ae Add disclaimer 2018-04-07 02:38:48 +02:00
Kamran Ahmed
c2f7754b0d Add updated backend developer roadmap 2018-04-02 18:28:52 +02:00
Kamran Ahmed
4df519845f Update roadmaps 2018-03-27 00:46:00 +02:00
Kamran Ahmed
910bd371dd Add backend and devops text files 2018-03-26 22:09:12 +02:00
Kamran Ahmed
0aa6db6007 Update textual form 2018-03-26 22:07:12 +02:00
Kamran Ahmed
01be603780 Rename readme 2018-03-26 22:04:14 +02:00
Kamran Ahmed
55a3ce4def Rename readme 2018-03-26 22:04:04 +02:00
Kamran Ahmed
a21264eb5e Remove splits 2018-03-26 22:00:43 +02:00
Kamran Ahmed
8c216782e5 Update markdown 2018-03-26 21:59:32 +02:00
Kamran Ahmed
ed9823245b Update structure 2018-03-26 21:56:13 +02:00
Kamran Ahmed
378e53eba4 Update frontend roadmap 2018-03-25 21:19:48 +02:00
Kamran Ahmed
66b68bc26f Add frontend map 2018-03-25 21:17:37 +02:00
Kamran Ahmed
0785d28bb4 Temp commit 2018-03-25 21:17:12 +02:00
Kamran Ahmed
f43dda522d Update frontend roadmap 2018-03-25 20:53:37 +02:00
Kamran Ahmed
ba98142d5b Remove recommendation 2018-03-25 18:16:24 +02:00
Kamran Ahmed
43160d3058 Put images in the repository 2018-03-25 18:03:57 +02:00
Kamran Ahmed
d40a858c6a Add disclaimer 2018-03-25 16:43:19 +02:00
Kamran Ahmed
4024005c4a Remove splits 2018-03-25 16:40:24 +02:00
Kamran Ahmed
91d1fc7245 Add massive disclaimer 2018-03-25 16:39:28 +02:00
Kamran Ahmed
328efa6ff6 Update frontend roadmap 2018-03-25 16:13:40 +02:00
Kamran Ahmed
cb352aba68 Add fancy splits 2018-02-27 21:31:39 +01:00
Kamran Ahmed
625ca5dcf4 Update youtube link 2018-02-27 13:53:02 +01:00
Kamran Ahmed
25d686ae5c Fix blog URL 2018-02-27 12:57:46 +01:00
Kamran Ahmed
0ab94faa95 Update README.md 2018-02-27 12:55:35 +01:00
Kamran Ahmed
5299a04acd Update README.md 2018-02-27 12:49:37 +01:00
Kamran Ahmed
f326a58bee Update readme 2018-02-27 12:49:07 +01:00
Kamran Ahmed
d8d52a6e86 Update readme 2018-02-27 12:42:05 +01:00
Kamran Ahmed
ba09cc4b86 Update readme 2018-02-27 12:22:14 +01:00
andrea
5804deb8ac Added a list of Linux & Unix server distributions, and Emacs as text editor (#328)
* Added a list of Linux & Unix server distributions, and Emacs as text editor

* Updated Linux server list personal preference and possibilities

* Added OpenBSD and NetBSD as unix suitable OS's
2018-02-27 09:57:27 +01:00
Zeeshan Ahmad
63b3f0199b Update README.md (#418) 2018-02-26 15:10:25 +01:00
Kamran Ahmed
0b0addaee4 Update readme 2018-02-24 20:44:01 +01:00
Kamran Ahmed
aab6d380aa Update project files 2018-01-06 17:16:47 +04:00
Ricardo N Feliciano
79b5c09a06 Add CircleCI, Packer, remove TeamCity, fix SaltStack. (#308) 2018-01-05 22:40:04 +04:00
Kamran Ahmed
3bd4ad5874 Update devops 2018-01-05 11:25:25 +04:00
Kamran Ahmed
79887dc7d5 Update intro 2018-01-05 03:16:54 +04:00
Kamran Ahmed
dc8cb8e777 Update charts for 2018 2018-01-05 03:14:25 +04:00
Kamran Ahmed
a8059e73c0 Update header image 2018-01-05 01:57:58 +04:00
PlanB
ee2b3e5de0 Change Flask's color to '16770457' (#292) 2017-11-28 09:21:36 +05:00
Kamran Ahmed
807e5ea2c1 Add sponsor link 2017-11-16 00:18:53 +04:00
Kamran Ahmed
f7b42203a4 Remove sponsor link 2017-11-03 12:27:26 +04:00
2988 changed files with 20973 additions and 38892 deletions

18
.eslintrc Normal file
View File

@@ -0,0 +1,18 @@
{
"extends": [
"next",
"next/core-web-vitals",
"prettier"
],
"rules": {
"@next/next/no-img-element": [
"off"
],
"react/display-name": [
"off"
],
"react/jsx-no-target-blank": [
"off"
]
}
}

36
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,36 @@
<!--
Please do not remove anything written below.
Fill the details and open the issue. Any issue that
doesn't have all of these filled in will be closed,
if yours is closed reopen with everything filled in.
-->
#### What roadmap is this issue about?
- [ ] Frontend Roadmap
- [ ] Backend Roadmap
- [ ] DevOps Roadmap
- [ ] All Roadmaps
#### What is this issue about?
- [ ] Functionality of the website
- [ ] Discussion for a pull request I would want to open.
- [ ] Addition of a new item
- [ ] Removal of some existing item
- [ ] Changing in arrangement
- [ ] General suggestion
- [ ] Sharing an Idea
- [ ] Something else
#### Please acknowledge the below listed
- [ ] This is not a duplicate issue. I have searched and there is no existing issue for this.
- [ ] I understand that these roadmaps are highly opinionated. The purpose is to not to include everything out there in these roadmaps but to have everything that is most relevant today comparing to the other options listed.
- [ ] I have read the [contribution docs](../contributing) before opening this issue.
#### Enter the details about the issue here
<!-- Please enter the issue details here -->

19
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,19 @@
#### What roadmap does this PR target?
- [ ] Code Change
- [ ] Frontend Roadmap
- [ ] Backend Roadmap
- [ ] DevOps Roadmap
- [ ] All Roadmaps
- [ ] Guides
#### Please acknowledge the items listed below
- [ ] I have discussed this contribution and got a go-ahead in an issue before opening this pull request.
- [ ] This is not a duplicate issue. I have searched and there is no existing issue for this.
- [ ] I understand that these roadmaps are highly opinionated. The purpose is to not to include everything out there in these roadmaps but to have everything that is most relevant today comparing to the other options listed.
- [ ] I have read the [contribution docs](../contributing) before opening this PR.
#### Enter the details about the contribution
<!-- Enter the details here -->

View File

@@ -1,21 +0,0 @@
name: Sends Daily AWS Costs to Slack
on:
# Allow manual Run
workflow_dispatch:
# Run at 7:00 UTC every day
schedule:
- cron: "0 7 * * *"
jobs:
aws_costs:
runs-on: ubuntu-latest
steps:
- name: Get Costs
env:
AWS_KEY: ${{ secrets.COST_AWS_ACCESS_KEY }}
AWS_SECRET: ${{ secrets.COST_AWS_SECRET_KEY }}
AWS_REGION: ${{ secrets.COST_AWS_REGION }}
SLACK_CHANNEL: ${{ secrets.SLACK_COST_CHANNEL }}
SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
run: |
npm install -g aws-cost-cli
aws-cost -k $AWS_KEY -s $AWS_SECRET -r $AWS_REGION -S $SLACK_TOKEN -C $SLACK_CHANNEL

View File

@@ -1,34 +1,28 @@
name: Deployment to GH Pages
name: Deployment to GitHub Pages
on:
push:
branches: [ master ]
env:
ROADMAP_GA_SECRET: ${{ secrets.GA_SECRET }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PAT: ${{ secrets.PAT }}
CI: true
NEXT_TELEMETRY_DISABLED: 1
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
- uses: actions/setup-node@v1
with:
node-version: 18
- run: git config --global url."https://${{ secrets.PAT }}@github.com/".insteadOf ssh://git@github.com/
- uses: pnpm/action-setup@v2.2.2
with:
version: 7.13.4
node-version: 14
- name: Setup Environment
run: |
pnpm install
- name: Generate meta and build
npm install
- name: Generate meta and builld
run: |
npm run meta
npm run build
touch ./dist/.nojekyll
echo 'roadmap.sh' > ./dist/CNAME
- name: Deploy to GH Pages
- name: Deploy to GitHub Pages
run: |
git config user.email "kamranahmed.se@gmail.com"
git config user.name "Kamran Ahmed"

View File

@@ -1,38 +0,0 @@
name: Update dependencies
on:
workflow_dispatch: # allow manual run
schedule:
- cron: '0 0 * * 0' # every sunday at midnight
jobs:
upgrade-deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: 18
- uses: pnpm/action-setup@v2.2.2
with:
version: 7.13.4
- name: Upgrade dependencies
run: |
pnpm install
npm run upgrade
pnpm install --lockfile-only
- name: Create PR
uses: peter-evans/create-pull-request@v4
with:
delete-branch: false
branch: "update-deps"
base: "master"
labels: |
dependencies
automated pr
reviewers: kamranahmedse
commit-message: "chore: update dependencies to latest"
title: "Upgrade dependencies to latest"
body: |
Updates all dependencies to latest versions.
Please review the changes and merge if everything looks good.

44
.gitignore vendored
View File

@@ -1,26 +1,36 @@
# build output
dist/
.output/
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
out
# dependencies
node_modules/
/node_modules
/.pnp
.pnp.js
bin/developer-roadmap
# testing
/coverage
# logs
# next.js
/.next/
/out/
# production
/build
# misc
.idea
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
/test-results/
/playwright-report/
/playwright/.cache/
tests-examples
# vercel
.vercel

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2
}

View File

@@ -1,4 +0,0 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}

11
.vscode/launch.json vendored
View File

@@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}

39
README.md Normal file
View File

@@ -0,0 +1,39 @@
<p align="center">
<img src="public/brand.png" height="128">
<h2 align="center">roadmap.sh</h2>
<p align="center">Community driven roadmaps, articles and resources for developers<p>
<p align="center">
<a href="https://roadmap.sh/guides">
<img src="https://img.shields.io/badge/-Guides-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
</a>
<a href="https://roadmap.sh/roadmaps">
<img src="https://img.shields.io/badge/-Roadmaps-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
</a>
<a href="./contributing/guide.md">
<img src="https://img.shields.io/badge/%E2%9D%A4-Contribute-0a0a0a.svg?style=flat&colorA=0a0a0a" alt="roadmaps" />
</a>
</p>
</p>
[roadmap.sh](https://roadmap.sh) is the community effort to create knowledge that is approachable for the developers.
The website is built with Next.js, contains roadmaps which are the step by step guides for developers, guides which are the easier to understand explanations on the complex topics. Anyone can contribute to the website by suggesting changes to existing paths, adding learning resources, becoming an author by adding new guides, updating the existing guides.
## Development
Clone the repository, install the dependencies and start the application
```bash
git clone https://github.com/kamranahmedse/roadmap.sh
yarn install
yarn dev
```
## Contributions
* Add new Roadmap
* Suggest changes to existing roadmap
* Write an article
* Improve the site's codebase
* Write tests

View File

@@ -1,42 +0,0 @@
// https://astro.build/config
import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind';
import compress from 'astro-compress';
import { defineConfig } from 'astro/config';
import rehypeExternalLinks from 'rehype-external-links';
import { serializeSitemap, shouldIndexPage } from './sitemap.mjs';
export default defineConfig({
site: 'https://roadmap.sh',
markdown: {
shikiConfig: {
theme: 'dracula',
},
rehypePlugins: [
[
rehypeExternalLinks,
{
target: '_blank',
},
],
],
},
build: {
format: 'file',
},
integrations: [
tailwind({
config: {
applyBaseStyles: false,
},
}),
sitemap({
filter: shouldIndexPage,
serialize: serializeSitemap,
}),
compress({
css: false,
js: false,
}),
],
});

View File

@@ -1,144 +0,0 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the best-practices
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/best-practices');
const bestPracticeId = process.argv[2];
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
if (!bestPracticeId) {
console.error('bestPractice is required');
process.exit(1);
}
if (!allowedBestPracticeId.includes(bestPracticeId)) {
console.error(`Invalid best practice key ${bestPracticeId}`);
console.error(`Allowed keys are ${allowedBestPracticeId.join(', ')}`);
process.exit(1);
}
// Directory holding the best parctice content files
const bestPracticeDirName = fs
.readdirSync(BEST_PRACTICE_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === bestPracticeId);
if (!bestPracticeDirName) {
console.error('Best practice directory not found');
process.exit(1);
}
const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName);
const bestPracticeContentDirPath = path.join(
BEST_PRACTICE_CONTENT_DIR,
bestPracticeDirName,
'content'
);
// If best practice content already exists do not proceed as it would override the files
if (fs.existsSync(bestPracticeContentDirPath)) {
console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`);
process.exit(1);
}
function prepareDirTree(control, dirTree) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// No directory for a group without control name
if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) {
return;
}
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlName.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree);
});
}
return { dirTree };
}
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`));
const controls = bestPractice.mockup.controls.control;
// Prepare the dir tree that we will be creating
const dirTree = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(bestPracticeContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(
path.join(parentDir, dirName),
dirTree[dirName],
filePaths
);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(bestPracticeContentDirPath, dirTree);
console.log('Created best practice content directory structure');

View File

@@ -1,19 +0,0 @@
const fs = require('node:fs');
const path = require('node:path');
const jsonsDir = path.join(process.cwd(), 'public/jsons');
const childJsonDirs = fs.readdirSync(jsonsDir);
childJsonDirs.forEach((childJsonDir) => {
const fullChildJsonDirPath = path.join(jsonsDir, childJsonDir);
const jsonFiles = fs.readdirSync(fullChildJsonDirPath);
jsonFiles.forEach((jsonFileName) => {
console.log(`Compressing ${jsonFileName}...`);
const jsonFilePath = path.join(fullChildJsonDirPath, jsonFileName);
const json = require(jsonFilePath);
fs.writeFileSync(jsonFilePath, JSON.stringify(json));
});
});

View File

@@ -1,28 +0,0 @@
## CLI Tools
> A bunch of CLI scripts to make the development easier
## `roadmap-links.cjs`
Generates a list of all the resources links in any roadmap file.
## `compress-jsons.cjs`
Compresses all the JSON files in the `public/jsons` folder
## `roadmap-content.cjs`
This command is used to create the content folders and files for the interactivity of the roadmap. You can use the below command to generate the roadmap skeletons inside a roadmap directory:
```bash
npm run roadmap-content [frontend|backend|devops|...]
```
For the content skeleton to be generated, we should have proper grouping, and the group names in the project files. You can follow the steps listed below in order to add the meta information to the roadmap.
- Remove all the groups from the roadmaps through the project editor. Select all and press `cmd+shift+g`
- Identify the boxes that should be clickable and group them together with `cmd+shift+g`
- Assign the name to the groups.
- Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information.
- Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`.

View File

@@ -1,163 +0,0 @@
const fs = require('fs');
const path = require('path');
const CONTENT_DIR = path.join(__dirname, '../content');
// Directory containing the roadmaps
const ROADMAP_CONTENT_DIR = path.join(__dirname, '../src/roadmaps');
const roadmapId = process.argv[2];
const allowedRoadmapIds = fs.readdirSync(ROADMAP_CONTENT_DIR);
if (!roadmapId) {
console.error('roadmapId is required');
process.exit(1);
}
if (!allowedRoadmapIds.includes(roadmapId)) {
console.error(`Invalid roadmap key ${roadmapId}`);
console.error(`Allowed keys are ${allowedRoadmapIds.join(', ')}`);
process.exit(1);
}
// Directory holding the roadmap content files
const roadmapDirName = fs
.readdirSync(ROADMAP_CONTENT_DIR)
.find((dirName) => dirName.replace(/\d+-/, '') === roadmapId);
if (!roadmapDirName) {
console.error('Roadmap directory not found');
process.exit(1);
}
const roadmapDirPath = path.join(ROADMAP_CONTENT_DIR, roadmapDirName);
const roadmapContentDirPath = path.join(
ROADMAP_CONTENT_DIR,
roadmapDirName,
'content'
);
// If roadmap content already exists do not proceed as it would override the files
if (fs.existsSync(roadmapContentDirPath)) {
console.error(`Roadmap content already exists @ ${roadmapContentDirPath}`);
process.exit(1);
}
function prepareDirTree(control, dirTree, dirSortOrders) {
// Directories are only created for groups
if (control.typeID !== '__group__') {
return;
}
// e.g. 104-testing-your-apps:other-options
const controlName = control?.properties?.controlName || '';
// e.g. 104
const sortOrder = controlName.match(/^\d+/)?.[0];
// No directory for a group without control name
if (!controlName || !sortOrder) {
return;
}
// e.g. testing-your-apps:other-options
const controlNameWithoutSortOrder = controlName.replace(/^\d+-/, '');
// e.g. ['testing-your-apps', 'other-options']
const dirParts = controlNameWithoutSortOrder.split(':');
// Nest the dir path in the dirTree
let currDirTree = dirTree;
dirParts.forEach((dirPart) => {
currDirTree[dirPart] = currDirTree[dirPart] || {};
currDirTree = currDirTree[dirPart];
});
dirSortOrders[controlNameWithoutSortOrder] = Number(sortOrder);
const childrenControls = control.children.controls.control;
// No more children
if (childrenControls.length) {
childrenControls.forEach((childControl) => {
prepareDirTree(childControl, dirTree, dirSortOrders);
});
}
return { dirTree, dirSortOrders };
}
const roadmap = require(path.join(__dirname, `../public/jsons/roadmaps/${roadmapId}`));
const controls = roadmap.mockup.controls.control;
// Prepare the dir tree that we will be creating and also calculate the sort orders
const dirTree = {};
const dirSortOrders = {};
controls.forEach((control) => {
prepareDirTree(control, dirTree, dirSortOrders);
});
/**
* @param parentDir Parent directory in which directory is to be created
* @param dirTree Nested dir tree to be created
* @param sortOrders Mapping from groupName to sort order
* @param filePaths The mapping from groupName to file path
*/
function createDirTree(parentDir, dirTree, sortOrders, filePaths = {}) {
const childrenDirNames = Object.keys(dirTree);
const hasChildren = childrenDirNames.length !== 0;
// @todo write test for this, yolo for now
const groupName = parentDir
.replace(roadmapContentDirPath, '') // Remove base dir path
.replace(/(^\/)|(\/$)/g, '') // Remove trailing slashes
.replace(/(^\d+?-)/g, '') // Remove sorting information
.replaceAll('/', ':') // Replace slashes with `:`
.replace(/:\d+-/, ':');
const humanizedGroupName = groupName
.split(':')
.pop()
?.replaceAll('-', ' ')
.replace(/^\w/, ($0) => $0.toUpperCase());
const sortOrder = sortOrders[groupName] || '';
// Attach sorting information to dirname
// e.g. /roadmaps/100-frontend/content/internet
// ———> /roadmaps/100-frontend/content/103-internet
if (sortOrder) {
parentDir = parentDir.replace(/(.+?)([^\/]+)?$/, `$1${sortOrder}-$2`);
}
// If no children, create a file for this under the parent directory
if (!hasChildren) {
let fileName = `${parentDir}.md`;
fs.writeFileSync(fileName, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = fileName.replace(CONTENT_DIR, '');
return filePaths;
}
// There *are* children, so create the parent as a directory
// and create `index.md` as the content file for this
fs.mkdirSync(parentDir);
let readmeFilePath = path.join(parentDir, 'index.md');
fs.writeFileSync(readmeFilePath, `# ${humanizedGroupName}`);
filePaths[groupName || 'home'] = readmeFilePath.replace(CONTENT_DIR, '');
// For each of the directory names, create a
// directory inside the given directory
childrenDirNames.forEach((dirName) => {
createDirTree(
path.join(parentDir, dirName),
dirTree[dirName],
dirSortOrders,
filePaths
);
});
return filePaths;
}
// Create directories and get back the paths for created directories
createDirTree(roadmapContentDirPath, dirTree, dirSortOrders);
console.log('Created roadmap content directory structure');

View File

@@ -1,44 +0,0 @@
const fs = require('fs');
const path = require('path');
const roadmapId = process.argv[2];
if (!roadmapId) {
console.error('Error: roadmapId is required');
}
const fullPath = path.join(__dirname, `../src/roadmaps/${roadmapId}`);
if (!fs.existsSync(fullPath)) {
console.error(`Error: path not found: ${fullPath}!`);
process.exit(1);
}
function readFiles(folderPath) {
const stats = fs.lstatSync(folderPath);
if (stats.isFile()) {
return [folderPath];
}
const folderContent = fs.readdirSync(folderPath);
let files = [];
for (const file of folderContent) {
const filePath = path.join(folderPath, file);
files = [...files, ...readFiles(filePath)];
}
return files;
}
const files = readFiles(fullPath);
let allLinks = [];
files.forEach((file) => {
const fileContent = fs.readFileSync(file, 'utf-8');
const matches = [...fileContent.matchAll(/\[[^\]]+]\((https?:\/\/[^)]+)\)/g)];
allLinks = [...allLinks, ...matches.map((match) => match[1])];
});
allLinks.map((link) => console.log(link));

View File

@@ -1,76 +0,0 @@
# Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <kamranahmed.se@gmail.com>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@@ -0,0 +1,60 @@
import { Box, Container, Flex, Heading, Image, Link, Text } from '@chakra-ui/react';
import React from 'react';
type ContentPageHeaderProps = {
formattedDate: string;
title: string;
subtitle: string;
author?: {
name: string;
twitter: string;
picture: string;
},
subLink?: {
text: string;
url: string;
}
};
export function ContentPageHeader(props: ContentPageHeaderProps) {
const { title, subtitle, author = null, formattedDate, subLink = null } = props;
return (
<Box pt={['35px', '35px', '70px']} pb={['35px', '35px', '55px']} borderBottomWidth={1} mb='30px'>
<Container maxW='container.md' position='relative' textAlign={['left', 'left', 'center']}>
<Flex alignItems='center' justifyContent={['flex-start', 'flex-start', 'center']}
fontSize={['12px', '12px', '14px']}>
{author?.name && (
<>
<Link
d={['none', 'flex', 'flex']}
target='_blank'
href={`https://twitter.com/${author.twitter}`}
alignItems='center'
fontWeight={600}
color='gray.500'
>
<Image alt={''} rounded={'full'} mr='7px' w='22px' src={author.picture} />
{author.name}
</Link>
<Text d={['none', 'inline', 'inline']} mx='7px' color='gray.500' as='span'>&middot;</Text>
</>
)}
<Text color='gray.500' as='span'>{formattedDate}</Text>
{subLink?.text && (
<>
<Text d={['none', 'none', 'inline']} mx='7px' color='gray.500' as='span'>&middot;</Text>
<Link d={['none', 'none', 'inline']} color='blue.500' fontWeight={500}
href={subLink.url} target={'_blank'}>{subLink.text}</Link>
</>
)}
</Flex>
<Heading as='h1' color='black' fontSize={['30px', '30px', '45px']} lineHeight={['40px', '40px', '53px']}
fontWeight={700} my={['5px', '5px', '10px']}>{title}</Heading>
<Text fontSize={['14px', '14px', '16px']} color='gray.700'>{subtitle}</Text>
</Container>
</Box>
);
}

37
components/custom-ad.tsx Normal file
View File

@@ -0,0 +1,37 @@
export const CustomAd = () => {
return (
<div id='carbonads'>
<span>
<span className='carbon-wrap'>
<a
href='https://freemote.com/strategy?sl=roadmap'
className='carbon-img'
target='_blank'
>
<img
src='/fm-img.png'
alt='FM Logo'
height='100'
width='130'
style={{ maxWidth: '130px', border: 'none' }}
/>
</a>
<a
href='https://freemote.com/strategy?sl=roadmap'
className='carbon-text'
target='_blank'
>
He Went from ZERO TO $74,000 as a Full Time Developer in 7 Weeks
</a>
</span>
<a
href='https://github.com/sponsors/kamranahmedse'
className='carbon-poweredby'
target='_blank'
>
Sponsored by
</a>
</span>
</div>
);
};

View File

@@ -0,0 +1,46 @@
import { Box, Link, Text } from '@chakra-ui/react';
type DimmedMoreProps = {
text: string;
href: string;
};
export function DimmedMore(props: DimmedMoreProps) {
const { text, href } = props;
return (
<Box position='relative' textAlign='center' bottom='20px'>
<Box
opacity={1}
pointerEvents='none'
position='absolute'
bottom={0}
height='200px'
width='100%'
background='linear-gradient(180deg, rgb(255 255 255 / 40%), white)'
/>
<Link
rounded='20px'
display='inline'
bg='green.600'
color='white'
p='7px 20px'
href={href}
fontWeight={800}
fontSize='11px'
textTransform='uppercase'
my='25px'
position='relative'
_hover={{
textDecoration: 'none',
'& .forward-arrow': {
transform: 'translateX(3px)'
}
}}>
{text}
<Text d='inline-block' as='span' transition='200ms' ml='4px' className='forward-arrow'>&rarr;</Text>
</Link>
</Box>
);
}

79
components/footer.tsx Normal file
View File

@@ -0,0 +1,79 @@
import { Box, Container, Flex, Image, Link, Stack, Text } from '@chakra-ui/react';
import siteConfig from '../content/site.json';
import { CustomAd } from './custom-ad';
function NavigationLinks() {
return (
<>
<Stack isInline d={['none', 'none', 'flex']} color='gray.400' fontWeight={600} spacing='30px'>
<Link _hover={{ color: 'white' }} href='/roadmaps'>Roadmaps</Link>
<Link _hover={{ color: 'white' }} href='/guides'>Guides</Link>
<Link _hover={{ color: 'white' }} href='/watch'>Videos</Link>
<Link _hover={{ color: 'white' }} href='/about'>About</Link>
<Link _hover={{ color: 'white' }} href={siteConfig.url.youtube} target='_blank'>YouTube</Link>
</Stack>
<Stack d={['flex', 'flex', 'none']} color='gray.400' fontWeight={600} spacing={0}>
<Link py='7px' borderBottomWidth={1} borderBottomColor='gray.800' _hover={{ color: 'white' }}
href='/roadmaps'>Roadmaps</Link>
<Link py='7px' borderBottomWidth={1} borderBottomColor='gray.800' _hover={{ color: 'white' }}
href='/guides'>Guides</Link>
<Link py='7px' borderBottomWidth={1} borderBottomColor='gray.800' _hover={{ color: 'white' }}
href='/watch'>Videos</Link>
<Link py='7px' borderBottomWidth={1} borderBottomColor='gray.800' _hover={{ color: 'white' }}
href='/thanks'>Thanks</Link>
<Link py='7px' borderBottomWidth={1} borderBottomColor='gray.800' _hover={{ color: 'white' }}
href='/about'>About</Link>
<Link py='7px' _hover={{ color: 'white' }} target='_blank'
href={siteConfig.url.youtube}>YouTube</Link>
</Stack>
</>
);
}
export function Footer() {
return (
<Box bg='gray.900' p={['25px 0', '25px 0', '40px 0']}>
<Container maxW='container.md'>
<NavigationLinks />
<Box mt={['40px', '40px', '50px']} mb='40px' maxW='500px'>
<Flex spacing={0} alignItems='center' color='gray.400'>
<Link d='flex' alignItems='center' fontWeight={600} _hover={{ textDecoration: 'none', color: 'white' }}
href='/'>
<Image alt='' h='25px' w='25px' src='/logo.svg' mr='6px' />
roadmap.sh
</Link>
<Text as='span' mx='7px'>by</Text>
<Link bg='blue.500' px='6px' py='2px' rounded='4px' color='white' fontWeight={600} fontSize='13px'
_hover={{ textDecoration: 'none', bg: 'blue.600' }} href={siteConfig.url.twitter}
target='_blank'>@kamranahmedse</Link>
</Flex>
<Text my='15px' fontSize='14px' color='gray.500'>Community created roadmaps, articles, resources and
journeys to help you choose your path and grow in your career.</Text>
<Text fontSize='14px' color='gray.500'>
<Text as='span' mr='10px'>&copy; roadmap.sh</Text>&middot;
<Link href='/about' _hover={{ textDecoration: 'none', color: 'white' }} color='gray.400'
mx='10px'>FAQs</Link>&middot;
<Link href='/terms' _hover={{ textDecoration: 'none', color: 'white' }} color='gray.400'
mx='10px'>Terms</Link>&middot;
<Link href='/privacy' _hover={{ textDecoration: 'none', color: 'white' }} color='gray.400'
mx='10px'>Privacy</Link>
</Text>
</Box>
</Container>
<CustomAd />
{process.env.GA_SECRET && false && (
<script
async
type='text/javascript'
src='//cdn.carbonads.com/carbon.js?serve=CE7DLK3Y&placement=roadmapsh'
id='_carbonads_js'
/>
)}
</Box>
);
}

View File

@@ -0,0 +1,113 @@
import { useState } from 'react';
import { HamburgerIcon } from '@chakra-ui/icons';
import { Box, CloseButton, Container, Flex, IconButton, Image, Link, Stack, Text } from '@chakra-ui/react';
import RoadmapLogo from '../components/icons/roadmap.svg';
import siteConfig from '../content/site.json';
type MenuLinkProps = {
text: string;
link: string;
};
function MenuLink(props: MenuLinkProps) {
const { text, link } = props;
return <Link
borderBottomWidth={0}
borderBottomColor='gray.500'
_hover={{ textDecoration: 'none', borderBottomColor: 'white' }}
fontWeight={500}
href={link}
>
{text}
</Link>;
}
function DesktopMenuLinks() {
return (
<Stack d={['none', 'flex', 'flex']} shouldWrapChildren isInline spacing='15px' alignItems='center' color='gray.50'
fontSize='15px'>
<MenuLink text={'Roadmaps'} link={'/roadmaps'} />
<MenuLink text={'Guides'} link={'/guides'} />
<MenuLink text={'Videos'} link={'/watch'} />
<MenuLink text={'Thanks'} link={'/thanks'} />
<Link ml='10px' bgGradient='linear(to-l, yellow.700, red.600)' p='7px 10px' rounded='4px'
_hover={{ textDecoration: 'none', bgGradient: 'linear(to-l, red.800, yellow.700)' }}
fontWeight={500} href={'/signup'}>Subscribe</Link>
</Stack>
);
}
function MobileMenuLinks() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<IconButton
rounded='5px'
padding={0}
aria-label={'Menu'}
d={['block', 'none', 'none']}
icon={<HamburgerIcon color='white' w='25px' height='25px' />}
color='white'
cursor='pointer'
h='auto'
bg='transparent'
_hover={{ bg: 'transparent' }}
_active={{ bg: 'transparent' }}
_focus={{ bg: 'transparent' }}
onClick={() => setIsOpen(true)}
/>
{isOpen && (
<Stack color='gray.100'
fontSize={['22px', '22px', '22px', '32px']}
alignItems='center'
justifyContent='center'
pos='fixed'
left={0}
right={0}
bottom={0}
top={0}
bg='gray.900'
spacing='12px'
zIndex={1}
>
<Link href='/roadmaps'>Roadmaps</Link>
<Link href='/guides'>Guides</Link>
<Link href='/watch'>Videos</Link>
<Link href='/thanks'>Thanks</Link>
<Link href='/signup'>Subscribe</Link>
<CloseButton onClick={() => setIsOpen(false)} pos='fixed' top='40px' right='15px' size='lg' />
</Stack>
)}
</>
);
}
export function GlobalHeader() {
return (
<Box bg='gray.900' p='58px 0 20px'>
<Container maxW='container.md'>
<Flex justifyContent='space-between' alignItems='center'>
<Box>
<Link w='100%'
d='flex'
href='/'
alignItems='center'
color='white'
fontWeight={600}
_hover={{ textDecoration: 'none' }}
fontSize='18px'>
<RoadmapLogo style={{ height: '30px', width: '30px', marginRight: '10px' }} />
<Text d={['block', 'none', 'block']} as='span'>roadmap.sh</Text>
</Link>
</Box>
<DesktopMenuLinks />
<MobileMenuLinks />
</Flex>
</Container>
</Box>
);
}

View File

@@ -0,0 +1,31 @@
import { Badge, Box, Heading, Link, Text } from '@chakra-ui/react';
type GuideGridItemProps = {
title: string;
href: string;
subtitle: string;
date: string;
isNew?: boolean;
colorIndex?: number;
};
const bgColorList = [
'gray.700',
'purple.800'
];
export function GuideGridItem(props: GuideGridItemProps) {
const { title, subtitle, date, isNew = false, colorIndex = 0, href } = props;
return (
<Box _hover={{ textDecoration: 'none', transform: 'scale(1.02)' }} as={Link} href={href} shadow='xl' p='20px'
rounded='10px' bg={bgColorList[colorIndex] ?? bgColorList[0]} flex={1}>
<Text mb='10px' fontSize='13px' color='gray.400'>
{isNew && <Badge colorScheme={'yellow'} mr='10px'>New</Badge>}
{date}
</Text>
<Heading color='white' mb={'6px'} fontSize='20px'>{title}</Heading>
<Text color='gray.300' fontSize='14px'>{subtitle}</Text>
</Box>
);
}

73
components/helmet.tsx Normal file
View File

@@ -0,0 +1,73 @@
import NextHead from 'next/head';
import siteConfig from '../content/site.json';
type HelmetProps = {
title?: string;
keywords?: string[];
canonical?: string;
description?: string;
};
const Helmet = (props: HelmetProps) => (
<NextHead>
<meta charSet='UTF-8' />
<title>{props.title || siteConfig.title}</title>
<meta name='description' content={props.description || siteConfig.description} />
<meta name='author' content={siteConfig.author} />
<meta name='keywords' content={props.keywords ? props.keywords.join(',') : siteConfig.keywords.join(',')} />
<meta name='viewport'
content='width=device-width, user-scalable=yes, initial-scale=1.0, maximum-scale=3.0, minimum-scale=1.0' />
{props.canonical && <link rel='canonical' href={props.canonical} />}
<meta httpEquiv='Content-Language' content='en' />
<meta property='og:title' content={props.title || siteConfig.title} />
<meta property='og:description' content={props.description || siteConfig.description} />
<meta property='og:image' content={`${siteConfig.url.web}${siteConfig.logoSquare}`} />
<meta property='og:url' content={siteConfig.url.web} />
<meta property='og:type' content='website' />
<meta property='article:publisher' content={`https://facebook.com/${siteConfig.facebook}`} />
<meta property='og:site_name' content={siteConfig.name} />
<meta property='article:author' content={siteConfig.author} />
<meta name='twitter:card' content='summary' />
<meta name='twitter:site' content={`@${siteConfig.twitter}`} />
<meta name='twitter:title' content={props.title || siteConfig.title} />
<meta name='twitter:description' content={props.description || siteConfig.description} />
<meta name='twitter:image' content={`${siteConfig.url.web}${siteConfig.logoSquare}`} />
<meta name='twitter:image:alt' content='roadmap.sh' />
<meta name='mobile-web-app-capable' content='yes' />
<meta name='apple-mobile-web-app-capable' content='yes' />
<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />
<link rel='apple-touch-icon' sizes='180x180' href='/manifest/apple-touch-icon.png' />
<meta name='msapplication-TileColor' content='#101010' />
<meta name='theme-color' content='#848a9a' />
<link rel='manifest' href='/manifest/manifest.json' />
<link rel='icon' type='image/png' sizes='32x32' href='/manifest/icon32.png' />
<link rel='icon' type='image/png' sizes='16x16' href='/manifest/icon16.png' />
<link rel='shortcut icon' href='/manifest/favicon.ico' type='image/x-icon' />
<link rel='icon' href='/manifest/favicon.ico' type='image/x-icon' />
{ /* Global Site Tag (gtag.js) - Google Analytics */}
{process.env.GA_SECRET && (
<>
<script async src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GA_SECRET}`} />
<script dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${process.env.GA_SECRET}');
`
}} />
</>
)}
</NextHead>
);
export default Helmet;

View File

@@ -0,0 +1,3 @@
<svg width="29" height="29">
<path d="M23.2 5H5.8a.8.8 0 0 0-.8.8V23.2c0 .44.35.8.8.8h9.3v-7.13h-2.38V13.9h2.38v-2.38c0-2.45 1.55-3.66 3.74-3.66 1.05 0 1.95.08 2.2.11v2.57h-1.5c-1.2 0-1.48.57-1.48 1.4v1.96h2.97l-.6 2.97h-2.37l.05 7.12h5.1a.8.8 0 0 0 .79-.8V5.8a.8.8 0 0 0-.8-.79"></path>
</svg>

After

Width:  |  Height:  |  Size: 298 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
</svg>

After

Width:  |  Height:  |  Size: 841 B

View File

@@ -0,0 +1,4 @@
<svg viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true">
<path fill-rule="evenodd"
d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path>
</svg>

After

Width:  |  Height:  |  Size: 474 B

View File

@@ -0,0 +1,4 @@
<svg width="30" height="30" viewBox="0 0 283 283" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 39C0 17.4609 17.4609 0 39 0H244C265.539 0 283 17.4609 283 39V244C283 265.539 265.539 283 244 283H39C17.4609 283 0 265.539 0 244V39Z" fill="black"></path>
<path d="M121.215 210.72C119.348 211.28 116.361 211.84 112.255 212.4C108.335 212.96 104.228 213.24 99.9347 213.24C95.828 213.24 92.0947 212.96 88.7347 212.4C85.5614 211.84 82.8547 210.72 80.6147 209.04C78.3747 207.36 76.6014 205.12 75.2947 202.32C74.1747 199.333 73.6147 195.507 73.6147 190.84V106.84C73.6147 102.547 74.3614 98.9067 75.8547 95.92C77.5347 92.7467 79.868 89.9467 82.8547 87.52C85.8414 85.0933 89.4814 82.9467 93.7747 81.08C98.2547 79.0267 103.015 77.2533 108.055 75.76C113.095 74.2667 118.321 73.1467 123.735 72.4C129.148 71.4667 134.561 71 139.975 71C148.935 71 156.028 72.7733 161.255 76.32C166.481 79.68 169.095 85.28 169.095 93.12C169.095 95.7333 168.721 98.3467 167.975 100.96C167.228 103.387 166.295 105.627 165.175 107.68C161.255 107.68 157.241 107.867 153.135 108.24C149.028 108.613 145.015 109.173 141.095 109.92C137.175 110.667 133.441 111.507 129.895 112.44C126.535 113.187 123.641 114.12 121.215 115.24V210.72ZM166.387 188.32C166.387 180.48 168.813 173.947 173.667 168.72C178.52 163.493 185.147 160.88 193.547 160.88C201.947 160.88 208.573 163.493 213.427 168.72C218.28 173.947 220.707 180.48 220.707 188.32C220.707 196.16 218.28 202.693 213.427 207.92C208.573 213.147 201.947 215.76 193.547 215.76C185.147 215.76 178.52 213.147 173.667 207.92C168.813 202.693 166.387 196.16 166.387 188.32Z" fill="white"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,3 @@
<svg width="29" height="29" fill="currentColor">
<path d="M22.05 7.54a4.47 4.47 0 0 0-3.3-1.46 4.53 4.53 0 0 0-4.53 4.53c0 .35.04.7.08 1.05A12.9 12.9 0 0 1 5 6.89a5.1 5.1 0 0 0-.65 2.26c.03 1.6.83 2.99 2.02 3.79a4.3 4.3 0 0 1-2.02-.57v.08a4.55 4.55 0 0 0 3.63 4.44c-.4.08-.8.13-1.21.16l-.81-.08a4.54 4.54 0 0 0 4.2 3.15 9.56 9.56 0 0 1-5.66 1.94l-1.05-.08c2 1.27 4.38 2.02 6.94 2.02 8.3 0 12.86-6.9 12.84-12.85.02-.24 0-.43 0-.65a8.68 8.68 0 0 0 2.26-2.34c-.82.38-1.7.62-2.6.72a4.37 4.37 0 0 0 1.95-2.51c-.84.53-1.81.9-2.83 1.13z"></path>
</svg>

After

Width:  |  Height:  |  Size: 550 B

View File

@@ -0,0 +1,21 @@
export function VideoIcon(props: any) {
return (
<svg
stroke='currentColor'
fill='currentColor'
strokeWidth='0'
viewBox='0 0 24 24'
height='1em'
width='1em'
xmlns='http://www.w3.org/2000/svg'
{...props}
>
<g>
<path fill='none' d='M0 0h24v24H0z' />
<path
d='M3 3.993C3 3.445 3.445 3 3.993 3h16.014c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 20.007V3.993zm7.622 4.422a.4.4 0 0 0-.622.332v6.506a.4.4 0 0 0 .622.332l4.879-3.252a.4.4 0 0 0 0-.666l-4.88-3.252z'
/>
</g>
</svg>
);
}

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill='currentColor'>
<path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"/>
</svg>

After

Width:  |  Height:  |  Size: 369 B

View File

@@ -0,0 +1,47 @@
import React from 'react';
import { Badge, Flex, Link, Text } from '@chakra-ui/react';
type LinksListItemProps = {
href: string;
title: string;
subtitle: string;
badgeText?: string;
icon?: React.ReactChild;
hideSubtitleOnMobile?: boolean;
};
export function LinksListItem(props: LinksListItemProps) {
const { title, subtitle, badgeText, icon, hideSubtitleOnMobile = false, href } = props;
return (
<Link
href={href}
fontSize={['14px', '14px', '15px']}
py='9px'
d='flex'
flexDirection={['column', 'row', 'row']}
fontWeight={500}
color='gray.600'
alignItems={['flex-start', 'center']}
justifyContent={'space-between'}
_hover={{
textDecoration: 'none',
color: 'blue.400',
'& .list-item-title': {
transform: 'translateX(10px)'
}
}}
isTruncated
maxWidth='100%'
>
<Flex alignItems='center' className='list-item-title' transition={'200ms'}>
{icon}
<Text maxWidth={'345px'} isTruncated as='span'>{title}</Text>
{badgeText &&
<Badge pos='relative' top='1px' variant='subtle' colorScheme='purple' ml='10px'>{badgeText}</Badge>}
</Flex>
<Text d={[hideSubtitleOnMobile ? 'none' : 'inline', 'inline']} mt={['3px', 0]} as='span'
fontSize={['11px', '11px', '12px']} color='gray.500'>{subtitle}</Text>
</Link>
);
}

21
components/links-list.tsx Normal file
View File

@@ -0,0 +1,21 @@
import React from 'react';
import { StackDivider, VStack } from '@chakra-ui/react';
type LinksListProps = {
children: React.ReactNode
};
export function LinksList(props: LinksListProps) {
const { children } = props;
return (
<VStack
rounded='5px'
divider={<StackDivider borderColor='gray.200' />}
spacing={0}
align='stretch'
>
{children}
</VStack>
);
}

View File

@@ -0,0 +1,20 @@
import React from 'react';
// @ts-ignore
import { MDXProvider } from '@mdx-js/react';
import { ChakraProvider } from '@chakra-ui/react';
import MdxComponents from './mdx-components';
import { roadmapTheme } from '../../styles/theme';
type MdRendererType = {
children: React.ReactNode
};
export default function MdRenderer(props: MdRendererType) {
return (
<ChakraProvider theme={roadmapTheme} resetCSS>
<MDXProvider components={MdxComponents}>
{props.children}
</MDXProvider>
</ChakraProvider>
);
};

View File

@@ -0,0 +1,26 @@
import React from 'react';
import styled from 'styled-components';
type EnrichedLinkProps = {
href: string;
children: React.ReactNode
}
const Link = styled.a`
font-weight: 600;
text-decoration: underline;
`;
const EnrichedLink = (props: EnrichedLinkProps) => {
// Is external URL or is a media URL
const isExternalUrl = /(^http(s)?:\/\/)|(\.(png|svg|jpeg|jpg)$)/.test(props.href);
return (
<Link href={props.href} target={isExternalUrl ? '_blank' : '_self'}>
{props.children}
</Link>
);
};
export default EnrichedLink;

View File

@@ -0,0 +1,21 @@
import React from 'react';
import { Link, Text, Badge } from '@chakra-ui/react';
type BadgeLinkType = {
target: string;
badgeText: string;
href: string;
children: React.ReactNode
};
export function BadgeLink(props: BadgeLinkType) {
const { target = '_blank', badgeText, href, children } = props;
return (
<Text mb={0}>
<Link fontWeight={500} textDecoration='underline' href={href} target={target}>
<Badge colorScheme={'purple'} style={{ position: 'relative', top: '-2px' }}>{badgeText}</Badge> {children}
</Link>
</Text>
);
}

View File

@@ -0,0 +1,27 @@
import styled from 'styled-components';
const BlockQuote = styled.blockquote`
padding: 16px 20px;
position: relative;
background: #e8e8e8;
border-radius: 5px;
margin-bottom: 18px;
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
}
p + h4 {
margin-top: 15px;
}
p {
margin: 0;
& + p {
margin-top: 10px;
}
}
`;
export default BlockQuote;

View File

@@ -0,0 +1,10 @@
import React from 'react';
import { Code as ChakraCode } from '@chakra-ui/react';
type CodeType = {
children: React.ReactNode;
}
export default function Code(props: CodeType) {
return <ChakraCode bg='blue.500'>{props.children}</ChakraCode>;
}

View File

@@ -0,0 +1,81 @@
import React from 'react';
import styled from 'styled-components';
import LinkIcon from 'components/icons/link.svg';
const linkify = (Component: React.FunctionComponent<any>) => {
return function EnrichedHeading(props: { children: string }): React.ReactNode {
const text = props.children;
const id = text.toLowerCase && text
.toLowerCase()
.replace(/[^\x00-\x7F]/g, '')
.replace(/\s+/g, '-')
.replace(/[?!]/g, '');
return (
<Component id={id}>
<HeaderLink href={`#${id}`}>
<LinkIcon />
</HeaderLink>
{props.children}
</Component>
);
};
};
const HeaderLink = styled.a`
position: absolute;
top: 0;
left: -25px;
width: 25px;
display: none;
height: 100%;
align-items: center;
justify-content: flex-start;
`;
const H1 = styled.h1`
position: relative;
font-size: 42px;
line-height: 40px;
font-weight: 700;
margin: 32px 0 10px !important;
&:hover ${HeaderLink} {
display: flex;
}
`;
const H2 = styled(H1).attrs({ as: 'h2' })`
font-size: 32px;
`;
const H3 = styled(H1).attrs({ as: 'h3' })`
margin: 22px 0 8px;
font-size: 30px;
`;
const H4 = styled(H1).attrs({ as: 'h4' })`
margin: 18px 0 8px;
font-size: 24px;
`;
const H5 = styled(H1).attrs({ as: 'h5' })`
margin: 14px 0 8px;
font-size: 18px;
`;
const H6 = styled(H1).attrs({ as: 'h6' })`
margin: 12px 0 8px;
font-size: 18px;
`;
const Headings = {
h1: linkify(H1),
h2: linkify(H2),
h3: linkify(H3),
h4: linkify(H4),
h5: linkify(H5),
h6: linkify(H6)
};
export default Headings;

View File

@@ -0,0 +1,47 @@
import styled from 'styled-components';
type IFrameProps = {
title: string;
src: string;
};
const AspectRatioBox = styled.div`
position: relative;
max-width: 100%;
margin-bottom: 18px;
&:before {
height: 0;
content: "";
display: block;
padding-bottom: 50%;
}
& > iframe {
overflow: hidden;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
`;
export default function IFrame(props: IFrameProps) {
return (
<AspectRatioBox>
<iframe
frameBorder={0}
title={props.title}
src={props.src}
allow={'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'}
allowFullScreen
/>
</AspectRatioBox>
);
}

View File

@@ -0,0 +1,7 @@
import styled from 'styled-components';
export const Img = styled.img`
max-width: 100%;
margin: 25px auto;
display: block;
`;

View File

@@ -0,0 +1,30 @@
import { Code } from '@chakra-ui/react';
import { P } from './p';
import Headings from './heading';
import { Pre } from './pre';
import BlockQuote from './blockquote';
import { Table } from './table';
import IFrame from './iframe';
import { Img } from './img';
import EnrichedLink from './a';
import { BadgeLink } from './badge-link';
import { Li, Ul } from './ul';
import PremiumBlock from './premium-block';
const MdxComponents = {
p: P,
...Headings,
pre: Pre,
blockquote: BlockQuote,
a: EnrichedLink,
table: Table,
iframe: IFrame,
img: Img,
code: Code,
BadgeLink: BadgeLink,
PremiumBlock: PremiumBlock,
ul: Ul,
li: Li
};
export default MdxComponents;

View File

@@ -0,0 +1,14 @@
import React from 'react';
import { Text } from '@chakra-ui/react';
import styled from 'styled-components';
type EnrichedTextType = {
children: React.ReactNode;
}
export const P = styled.p`
line-height: 27px;
font-size: 16px;
color: black;
margin-bottom: 18px;
`;

View File

@@ -0,0 +1,12 @@
import styled from 'styled-components';
export const Pre = styled.pre`
margin: 25px -25px 25px -25px !important;
padding: 20px 25px !important;
border-radius: 10px;
line-height: 1.5 !important;
code {
background: transparent;
}
`;

View File

@@ -0,0 +1,19 @@
import React from 'react';
import { Box, Button, Heading, Text } from '@chakra-ui/react';
import { LockIcon } from '@chakra-ui/icons';
type PremiumBlockProps = {
title: string;
description: string;
};
export default function PremiumBlock(props: PremiumBlockProps) {
return (
<Box p='40px' textAlign='center' rounded='5px' mb='18px' bg='gray.50' borderWidth={1}>
<LockIcon color='gray.300' height='45px' w='45px' mb='18px' />
<Heading as='h3' fontSize='30px' mb='10px'>{props.title}</Heading>
<Text mb='18px'>{props.description}</Text>
<Button colorScheme='green'>Become a Member</Button>
</Box>
);
}

View File

@@ -0,0 +1,25 @@
import styled from 'styled-components';
export const Table = styled.table`
border-collapse: separate;
width: 100%;
border-spacing: 0;
margin: 20px 0;
th {
color: #666;
font-size: 12px;
font-weight: 400;
background: #FAFAFA;
text-transform: uppercase;
height: 40px;
vertical-align: middle;
padding: 5px 10px;
}
td {
font-size: 14px;
padding: 10px;
border-bottom: 1px solid #EAEAEA;
}
`;

View File

@@ -0,0 +1,12 @@
import React from 'react';
import { UnorderedList } from '@chakra-ui/react';
import styled from 'styled-components';
export const Ul = styled.ul`
margin-left: 40px;
margin-bottom: 18px;
`;
export const Li = styled.li`
margin-bottom: 7px;
`;

View File

@@ -0,0 +1,46 @@
import { Box, Container, Heading, Link, Text } from '@chakra-ui/react';
export function OpensourceBanner() {
return (
<Box borderTopWidth={1} pt={['45px', '45px', '70px']} pb={['20px', '20px', '30px']} textAlign='center'>
<Container maxW='container.md'>
<Heading fontSize={['25px', '25px', '35px']} mb={['10px', '10px', '20px']}>Open Source</Heading>
<Text lineHeight='26px' fontSize={['15px', '15px', '16px']} mb='20px'>The project is OpenSource,&nbsp;
<Link
_hover={{ textDecoration: 'none' }}
href='https://github.com/search?o=desc&q=stars%3A%3E100000&s=stars&type=Repositories'
target='_blank'
borderBottomWidth={1}
fontWeight={600}
>7th most starred project on GitHub</Link> and is visited by hundreds of thousands of
developers every month.</Text>
<iframe
src='https://ghbtns.com/github-btn.html?user=kamranahmedse&repo=developer-roadmap&type=star&count=true&size=large'
frameBorder='0'
scrolling='0'
width='170'
height='30'
style={{ margin: 'auto', marginBottom: '30px' }}
title='GitHub'
/>
<Text lineHeight={['25px', '25px', '26px']} fontSize={['15px', '15px', '16px']} mb='15px'>A considerable amount of my time is spent doing unpaid
community work on things that I hope will help humanity in some way. Your sponsorship helps me continue to
produce more open-source and free educational material consumed by hundreds of thousands of developers every
month.</Text>
<Box>
<iframe
src='https://ghbtns.com/github-btn.html?user=kamranahmedse&type=sponsor&size=large'
frameBorder='0'
scrolling='0'
width='260'
height='30'
title='GitHub'
style={{ margin: 'auto' }}
/>
</Box>
</Container>
</Box>
);
}

View File

@@ -0,0 +1,35 @@
import { Box, Container, Heading, Text } from '@chakra-ui/react';
import React from 'react';
type PageHeaderProps = {
title: string;
subtitle: string;
children?: React.ReactNode;
};
export function PageHeader(props: PageHeaderProps) {
const { title, subtitle, children } = props;
return (
<Box pt={['25px', '20px', '45px']} pb={['20px', '15px', '30px']} borderBottomWidth={1} mb='30px'>
<Container maxW='container.md' position='relative'>
<Heading
as='h1'
color='black'
fontSize={['28px', '33px', '40px']}
fontWeight={700}
mb={['2px', '2px', '5px']}
>
{title}
</Heading>
<Text fontSize={['13px', '14px', '15px']}>{subtitle}</Text>
</Container>
{children && (
<Container maxW='container.md'>
{children}
</Container>
)}
</Box>
);
}

View File

@@ -0,0 +1,47 @@
import { Box, Heading, Link, Text, Tooltip } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons';
type RoadmapGridItemProps = {
title: string;
subtitle: string;
isCommunity?: boolean;
colorIndex?: number;
url: string;
};
const bgColorList = [
'blue.900',
'red.800',
'green.800',
'teal.800',
'gray.800',
'red.900'
];
export function HomeRoadmapItem(props: RoadmapGridItemProps) {
const { title, subtitle, isCommunity, colorIndex = 0, url } = props;
return (
<Box
as={Link}
href={url}
_hover={{ textDecoration: 'none', transform: 'scale(1.02)' }}
flex={1}
shadow='2xl'
bg={bgColorList[colorIndex] ?? bgColorList[0]}
color='white'
p='15px'
rounded='10px'
pos='relative'
>
{isCommunity && (
<Tooltip label={'Community contribution'} hasArrow placement='top'>
<InfoIcon opacity={0.5} position='absolute' top='10px' right='10px' />
</Tooltip>
)}
<Heading fontSize={['17px', '17px', '22px']} mb='5px'>{title}</Heading>
<Text color='gray.200' fontSize={['13px']}>{subtitle}</Text>
</Box>
);
}

View File

@@ -0,0 +1,89 @@
import { Badge, Box, Flex, Heading, Link, Text, Tooltip } from '@chakra-ui/react';
import { InfoIcon } from '@chakra-ui/icons';
type RoadmapGridItemProps = {
title: string;
subtitle: string;
href: string;
isCommunity?: boolean;
isUpcoming?: boolean;
colorIndex?: number;
};
const bgColorList = [
'gray.900',
'purple.900',
'blue.900',
'red.900',
'green.900',
'teal.900',
'yellow.900',
'cyan.900',
'pink.900',
'gray.800',
'purple.800',
'blue.800',
'red.800',
'green.800',
'teal.800',
'yellow.800',
'cyan.800',
'pink.800',
'gray.700',
'purple.700',
'blue.700',
'red.700',
'green.700',
'teal.700',
'yellow.700',
'cyan.700',
'pink.700',
'gray.600',
'purple.600',
'blue.600',
'red.600',
'green.600',
'teal.600',
'yellow.600',
'cyan.600',
'pink.600'
];
export function RoadmapGridItem(props: RoadmapGridItemProps) {
const { title, subtitle, isCommunity = false, isUpcoming = false, colorIndex = 0, href = '/' } = props;
return (
<Box _hover={{ textDecoration: 'none', transform: 'scale(1.02)' }} as={Link} href={href} shadow='xl' p='20px'
rounded='10px' bg={bgColorList[colorIndex] ?? bgColorList[0]} flex={1} pos='relative'>
{isCommunity && (
<Tooltip label={'Community contribution'} hasArrow placement='top'>
<InfoIcon opacity={0.5} color='gray.100' position='absolute' top='10px' right='10px' />
</Tooltip>
)}
<Heading color='white' mb={'6px'} fontSize='20px'>{title}</Heading>
<Text color='gray.300' fontSize='14px'>{subtitle}</Text>
{isUpcoming && (
<Flex
alignItems='center'
justifyContent='center'
pos='absolute'
left={0}
right={0}
top={0}
bottom={0}
rounded='10px'
>
<Text color='white' bg='yellow.900' zIndex={1} fontWeight={600} p={'5px 10px'}
rounded='10px'>Upcoming</Text>
<Box bg={'black'} pos='absolute' top={0} left={0} right={0} bottom={0} rounded={'10px'} opacity={0.5} />
</Flex>
)}
</Box>
);
}

View File

@@ -0,0 +1,31 @@
import { Flex, Link, Text } from '@chakra-ui/react';
import YouTubeLogo from '../components/icons/youtube.svg';
import siteConfig from '../content/site.json';
export function StickyBanner() {
return (
<Flex as={Link}
href={siteConfig.url.youtube}
bg={'yellow.300'}
color='gray.900'
// bg={'teal.900'}
// color='gray.300'
alignItems='center'
position='fixed'
left={0}
right={0}
zIndex={999}
justifyContent='center'
py='8px'
_hover={{ textDecoration: 'none', bg: 'yellow.400' }}
// _hover={{ textDecoration: 'none', bg: 'teal.800', color: 'gray.100' }}
target='_blank'
>
<YouTubeLogo style={{ height: '20px', display: 'inline-block', marginRight: '7px' }} />
<Text as='span' fontWeight={500} fontSize='14px'>
<Text as='span'>We now have a YouTube Channel. <Text as='span' d={['none', 'inline']}>Subscribe for the video
content.</Text></Text>
</Text>
</Flex>
);
}

View File

@@ -0,0 +1,40 @@
import { Box, Button, Container, Flex, Heading, Link, Text } from '@chakra-ui/react';
import siteConfig from '../content/site.json';
export function UpdatesBanner() {
return (
<Box borderTopWidth={1} mt='60px' pt={['40px', '40px', '70px']} pb={['40px', '45px', '80px']} textAlign='left'
bg='gray.800'>
<Container maxW='container.md'>
<Heading color={'gray.100'} fontSize={['25px', '25px', '35px']} mb={['5px', '5px', '15px']}>Stay
Informed</Heading>
<Text color='gray.400' lineHeight='26px' fontSize={['15px', '15px', '16px']} mb='20px'>Subscribe yourself to get
updates, new
guides, videos and roadmaps in your inbox.</Text>
<Flex flexDirection={['column', 'column', 'row']}>
<Box mr={['0', '0', '20px']} mb={['15px', '15px', 0]}>
<Button as={Link} href='/signup' width={['full', 'auto']} fontSize={['14px', '14px', '16px']}
variant='outline' borderWidth={2}
colorScheme='green' _hover={{ color: 'green.200', textDecoration: 'none' }}>
Subscribe to Updates
</Button>
<Text color='gray.500' fontSize='13px' mt='5px'>Free subscription for updates</Text>
</Box>
<Box>
<Button as={Link}
href={siteConfig.url.sponsor}
target='_blank'
width={['full', 'auto']}
fontSize={['14px', '14px', '16px']}
_hover={{ textDecoration: 'none', bg: 'yellow.500' }}
colorScheme='yellow'>Updates & Paid Content</Button>
<Text color='gray.500' fontSize='13px' mt='5px'>Support the project by paying as little as <Text as='span'
fontWeight={600}>5$
per month</Text></Text>
</Box>
</Flex>
</Container>
</Box>
);
}

View File

@@ -0,0 +1,70 @@
import { Badge, Box, Heading, Link, Text } from '@chakra-ui/react';
type VideoGridItemProps = {
href: string;
title: string;
subtitle: string;
date: string;
isNew?: boolean;
isPro?: boolean;
colorIndex?: number;
};
const bgColorList = [
'gray.900',
'purple.900',
'blue.900',
'red.900',
'green.900',
'teal.900',
'yellow.900',
'cyan.900',
'pink.900',
'gray.800',
'purple.800',
'blue.800',
'red.800',
'green.800',
'teal.800',
'yellow.800',
'cyan.800',
'pink.800',
'gray.700',
'purple.700',
'blue.700',
'red.700',
'green.700',
'teal.700',
'yellow.700',
'cyan.700',
'pink.700',
'gray.600',
'purple.600',
'blue.600',
'red.600',
'green.600',
'teal.600',
'yellow.600',
'cyan.600',
'pink.600'
];
export function VideoGridItem(props: VideoGridItemProps) {
const { title, subtitle, date, isNew = false, isPro = false, colorIndex = 0, href } = props;
return (
<Box _hover={{ textDecoration: 'none', transform: 'scale(1.02)' }} as={Link} href={ href } shadow='xl' p='20px'
rounded='10px' bg={bgColorList[colorIndex] ?? bgColorList[0]} flex={1}>
<Text mb='7px' fontSize='12px' color='gray.400'>
{isNew && <Badge colorScheme={'yellow'} mr='10px'>New</Badge>}
{isPro && <Badge colorScheme={'blue'} mr='10px'>PRO</Badge>}
{date}
</Text>
<Heading color='white' mb={'6px'} fontSize='20px' lineHeight={'28px'}>{title}</Heading>
<Text color='gray.300' fontSize='14px'>{subtitle}</Text>
</Box>
);
}

43
content/authors.json Normal file
View File

@@ -0,0 +1,43 @@
[
{
"username": "kamranahmedse",
"name": "Kamran Ahmed",
"twitter": "kamranahmedse",
"picture": "/authors/kamranahmedse.jpeg",
"bio": "Lead engineer at Tajawal. Lover of all things web and opensource. Created roadmap.sh to help the confused ones."
},
{
"username": "jesse",
"name": "Jesse Li",
"twitter": "__jesse_li",
"picture": "/authors/jesse.png",
"bio": "Software engineer."
},
{
"username": "dmytrobol",
"name": "Dmytro Bolkachov",
"twitter": "dmytrobol",
"picture": "/authors/dmytrobol.png",
"bio": "JavaScript Lad, Movie buff and coder interested in everything web related"
},
{
"username": "spekulatius",
"name": "Peter Thaleikis",
"twitter": "spekulatius1984",
"picture": "/authors/spekulatius.jpg",
"bio": "Developer building side-projects for fun, lover of the web and open source"
},
{
"username": "ebrahimbharmal007",
"name": "Ebrahim Bharmal",
"twitter": "BharmalEbrahim",
"picture": "/authors/ebrahimbharmal007.png",
"bio": "Love building projects using tools completely new to me. Python forever. Senior at University of Texas at Arlington (2021)"
},
{
"username": "lesovsky",
"name": "Alexey Lesovsky",
"bio": "Linux system administrator and PostgreSQL DBA at DataEgret.",
"picture": "/authors/lesovsky.jpeg"
}
]

247
content/guides.json Normal file
View File

@@ -0,0 +1,247 @@
[
{
"id": "what-are-web-vitals",
"title": "What are Web Vitals?",
"description": "Learn what are the core web vitals and how to measure them.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2021-09-05T19:59:14.191Z",
"createdAt": "2021-09-05T19:59:14.191Z"
},
{
"id": "what-is-sli-slo-sla",
"title": "SLIs, SLOs and SLAs",
"description": "Learn what are different indicators for performance identification of any service.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2021-08-31T19:59:14.191Z",
"createdAt": "2021-08-31T19:59:14.191Z"
},
{
"id": "ci-cd",
"title": "What is CI and CD?",
"description": "Learn the basics of CI/CD and how to implement that with GitHub Actions.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-07-09T19:59:14.191Z",
"createdAt": "2020-07-09T19:59:14.191Z"
},
{
"id": "sso",
"title": "SSO — Single Sign On",
"description": "Learn the basics of SAML and understand how does Single Sign On work.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-07-01T19:59:14.191Z",
"createdAt": "2020-07-01T19:59:14.191Z"
},
{
"id": "oauth",
"title": "OAuth — Open Authorization",
"description": "Learn and understand what is OAuth and how it works",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-06-28T19:59:14.191Z",
"createdAt": "2020-06-28T19:59:14.191Z"
},
{
"id": "jwt-authentication",
"title": "JWT Authentication",
"description": "Understand what is JWT authentication and how is it implemented",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-06-20T19:59:14.191Z",
"createdAt": "2020-06-20T19:59:14.191Z"
},
{
"id": "token-authentication",
"title": "Token Based Authentication",
"description": "Understand what is token based authentication and how it is implemented",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-06-02T20:59:14.191Z",
"createdAt": "2020-06-02T20:59:14.191Z"
},
{
"id": "session-authentication",
"title": "Session Based Authentication",
"description": "Understand what is session based authentication and how it is implemented",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-26T20:59:14.191Z",
"createdAt": "2020-05-26T20:59:14.191Z"
},
{
"id": "basic-authentication",
"title": "Basic Authentication",
"description": "Understand what is basic authentication and how it is implemented",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-19T20:59:14.191Z",
"createdAt": "2020-05-19T20:59:14.191Z"
},
{
"id": "character-encodings",
"title": "Character Encodings",
"description": "Covers the basics of character encodings and explains ASCII vs Unicode",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-14T20:59:14.191Z",
"createdAt": "2020-05-14T20:59:14.191Z"
},
{
"id": "unfamiliar-codebase",
"title": "Unfamiliar Codebase",
"description": "Tips on getting getting familiar with an unfamiliar codebase",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-05-04T20:59:14.191Z",
"createdAt": "2020-05-04T20:59:14.191Z"
},
{
"id": "why-build-it-and-they-will-come-wont-work-anymore",
"title": "Build it and they will come?",
"description": "Why “build it and they will come” alone wont work anymore",
"isPro": false,
"authorUsername": "spekulatius",
"updatedAt": "2020-05-04T12:59:14.191Z",
"createdAt": "2020-05-04T12:59:14.191Z"
},
{
"id": "dhcp-in-one-picture",
"title": "DHCP in One Picture",
"description": "Here is what happens when a new device joins the network.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-04-28T15:48:21.191Z",
"createdAt": "2020-04-28T15:48:21.191Z"
},
{
"id": "ssl-tls-https-ssh",
"title": "SSL vs TLS vs SSH",
"description": "Quick tidbit on the differences between SSL, TLS, HTTPS and SSH",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-04-22T15:48:21.191Z",
"createdAt": "2020-04-22T15:48:21.191Z"
},
{
"id": "asymptotic-notation",
"title": "Asymptotic Notation",
"description": "Learn the basics of measuring the time and space complexity of algorithms",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-04-03T15:48:21.191Z",
"createdAt": "2020-04-03T15:48:21.191Z"
},
{
"id": "big-o-notation",
"title": "Big-O Notation",
"description": "Easy to understand explanation of Big-O notation without any fancy terms",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-03-15T15:48:21.191Z",
"createdAt": "2020-03-15T15:48:21.191Z"
},
{
"id": "random-numbers",
"title": "Random Numbers: Are they?",
"description": "Learn how they are generated and why they may not be truly random.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-03-14T15:48:21.191Z",
"createdAt": "2020-03-14T15:48:21.191Z"
},
{
"id": "scaling-databases",
"title": "Scaling Databases",
"description": "Learn the ups and downs of different database scaling strategies",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2020-02-18T15:48:21.191Z",
"createdAt": "2020-02-18T15:48:21.191Z"
},
{
"id": "what-is-internet",
"title": "How does the internet work?",
"description": "Learn the basics of internet and everything involved with this short video series",
"isPro": false,
"authorUsername": "dmytrobol",
"updatedAt": "2020-02-29T15:48:21.191Z",
"createdAt": "2020-02-29T15:48:21.191Z"
},
{
"id": "torrent-client",
"title": "Building a BitTorrent Client",
"description": "Learn everything you need to know about BitTorrent by writing a client in Go",
"isPro": false,
"authorUsername": "jesse",
"updatedAt": "2020-01-17T15:48:21.191Z",
"createdAt": "2020-01-17T15:48:21.191Z",
"canonical": "https://blog.jse.li/posts/torrent/"
},
{
"id": "levels-of-seniority",
"title": "Levels of Seniority",
"description": "How to Step Up as a Junior, Mid Level or a Senior Developer?",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2019-12-03T12:13:00.860Z",
"createdAt": "2019-12-03T12:13:00.860Z"
},
{
"id": "design-patterns-for-humans",
"title": "Design Patterns for Humans",
"description": "A language agnostic, ultra-simplified explanation to design patterns",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2019-10-09T12:00:00.860Z",
"createdAt": "2019-01-23T17:00:00.860Z"
},
{
"id": "journey-to-http2",
"title": "Journey to HTTP/2",
"description": "The evolution of HTTP. How it all started and where we stand today",
"isPro": false,
"authorUsername": "kamranahmedse",
"createdAt": "2018-12-04T12:00:00.860Z",
"updatedAt": "2018-12-04T12:00:00.860Z",
"isDraft": true
},
{
"id": "dns-in-one-picture",
"title": "DNS in One Picture",
"description": "Quick illustrative guide on how a website is found on the internet.",
"isPro": false,
"authorUsername": "kamranahmedse",
"updatedAt": "2018-12-04T12:00:00.860Z",
"createdAt": "2018-12-04T17:00:00.860Z"
},
{
"id": "http-caching",
"title": "HTTP Caching",
"description": "Everything you need to know about web caching",
"isPro": false,
"authorUsername": "kamranahmedse",
"createdAt": "2018-11-29T17:00:00.860Z",
"updatedAt": "2018-11-29T17:00:00.860Z"
},
{
"id": "history-of-javascript",
"title": "Brief History of JavaScript",
"description": "How JavaScript was introduced and evolved over the years",
"isPro": false,
"authorUsername": "kamranahmedse",
"createdAt": "2017-10-28T17:00:00.860Z",
"updatedAt": "2017-10-28T17:00:00.860Z"
},
{
"id": "proxy-servers",
"title": "Proxy Servers",
"description": "How do proxy servers work and what are forward and reverse proxies?",
"isPro": false,
"authorUsername": "ebrahimbharmal007",
"createdAt": "2020-07-24T12:40:18",
"updatedAt": "2020-07-24T12:40:18"
}
]

View File

@@ -0,0 +1,16 @@
export const guideMeta = {
"title": "WebStorm — Project History",
"description": "Learn how to peek through the history of any git repository to learn how it grew.",
"url": "/guides/project-history",
"fileName": "project-history",
"featured": true,
"author": "kamranahmedse",
"updatedAt": "2020-07-16T19:59:14.191Z",
"createdAt": "2020-07-16T19:59:14.191Z"
};
Asymptotic notation is the standard way of measuring the time and space that an algorithm will consume as the input grows. In one of my last guides, I covered "Big-O notation" and a lot of you asked for a similar one for Asymptotic notation. You can find the [previous guide here](/guides/big-o-notation).
[![](/guides/asymptotic-notation.png)](/guides/asymptotic-notation.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1243861514907418624) where this image was posted.

View File

@@ -0,0 +1,3 @@
[![](/guides/basic-authentication.png)](/guides/basic-authentication.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1261783266044063748) where this image was posted.

View File

@@ -0,0 +1,5 @@
Big-O notation is the mathematical notation that helps analyse the algorithms to get an idea about how they might perform as the input grows. The image below explains Big-O in a simple way without using any fancy terminology.
[![](/guides/big-o-notation.png)](/guides/big-o-notation.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1235708842610212864) where this image was posted.

View File

@@ -0,0 +1,3 @@
[![](/guides/character-encodings.png)](/guides/character-encodings.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1259631582362689537) where this image was posted.

5
content/guides/ci-cd.md Normal file
View File

@@ -0,0 +1,5 @@
The image below details the differences between the continuous integration and continuous delivery. Also, here is the [accompanying video on implementing that with GitHub actions](https://www.youtube.com/watch?v=nyKZTKQS_EQ).
[![](/guides/ci-cd.png)](/guides/ci-cd.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1282806173939511298) where this image was posted.

View File

@@ -1,25 +1,3 @@
---
title: "Design Patterns for Humans"
description: "A language agnostic, ultra-simplified explanation to design patterns"
author:
name: "Kamran Ahmed"
url: "https://twitter.com/kamranahmedse"
imageUrl: "/authors/kamranahmedse.jpeg"
seo:
title: "Design Patterns for Humans - roadmap.sh"
description: "A language agnostic, ultra-simplified explanation to design patterns"
isNew: false
type: "textual"
date: 2019-01-23
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
Design patterns are solutions to recurring problems; **guidelines on how to tackle certain problems**. They are not classes, packages or libraries that you can plug into your application and wait for the magic to happen. These are, rather, guidelines on how to tackle certain problems in certain situations.
> Design patterns are solutions to recurring problems; guidelines on how to tackle certain problems

View File

@@ -0,0 +1,3 @@
[![](/guides/dhcp.png)](/guides/dhcp.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1254142557417857025) where this image was posted.

View File

@@ -1,27 +1,5 @@
---
title: "DNS in One Picture"
description: "Quick illustrative guide on how a website is found on the internet."
author:
name: "Kamran Ahmed"
url: "https://twitter.com/kamranahmedse"
imageUrl: "/authors/kamranahmedse.jpeg"
seo:
title: "DNS in One Picture - roadmap.sh"
description: "Quick illustrative guide on how a website is found on the internet."
isNew: false
type: "visual"
date: 2018-12-04
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "visual-guide"
- "guide-sitemap"
---
DNS or Domain Name System is one of the fundamental blocks of the internet. As a developer, you should have at-least the basic understanding of how it works. This article is a brief introduction to what is DNS and how it works.
DNS at its simplest is like a phonebook on your mobile phone. Whenever you have to call one of your contacts, you can either dial their number from your memory or use their name which will then be used by your mobile phone to search their number in your phone book to call them. Every time you make a new friend, or your existing friend gets a mobile phone, you have to memorize their phone number or save it in your phonebook to be able to call them later on. DNS or Domain Name System, in a similar fashion, is a mechanism that allows you to browse websites on the internet. Just like your mobile phone does not know how to call without knowing the phone number, your browser does not know how to open a website just by the domain name; it needs to know the IP Address for the website to open. You can either type the IP Address to open, or provide the domain name and press enter which will then be used by your browser to find the IP address by going through several hoops. The picture below is the illustration of how your browser finds a website on the internet.
[![DNS in One Picture](https://i.imgur.com/z9rwm5A.png)](https://i.imgur.com/z9rwm5A.png)
[![](https://i.imgur.com/z9rwm5A.png)](https://i.imgur.com/z9rwm5A.png)

View File

@@ -1,29 +1,7 @@
---
title: "Brief History of JavaScript"
description: "How JavaScript was introduced and evolved over the years"
author:
name: "Kamran Ahmed"
url: "https://twitter.com/kamranahmedse"
imageUrl: "/authors/kamranahmedse.jpeg"
seo:
title: "Brief History of JavaScript - roadmap.sh"
description: "How JavaScript was introduced and evolved over the years"
isNew: false
type: "textual"
date: 2017-10-28
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
Around 10 years ago, Jeff Atwood (the founder of stackoverflow) made a case that JavaScript is going to be the future and he coined the “Atwood Law” which states that *Any application that can be written in JavaScript will eventually be written in JavaScript*. Fast-forward to today, 10 years later, if you look at it it rings truer than ever. JavaScript is continuing to gain more and more adoption.
### JavaScript is announced
JavaScript was initially created by [Brendan Eich](https://twitter.com/BrendanEich) of NetScape and was first announced in a press release by Netscape in 1995. It has a bizarre history of naming; initially it was named `Mocha` by the creator, which was later renamed to `LiveScript`. In 1996, about a year later after the release, NetScape decided to rename it to be `JavaScript` with hopes of capitalizing on the Java community (although JavaScript did not have any relationship with Java) and released Netscape 2.0 with the official support of JavaScript.
JavaScript was initially created by [Brendan Eich](https://twitter.com/BrendanEich) of NetScape and was first announced in a press release by Netscape in 1995. It has a bizarre history of naming; initally it was named `Mocha` by the creator, which was later renamed to `LiveScript`. In 1996, about a year later after the release, NetScape decided to rename it to be `JavaScript` with hopes of capitalizing on the Java community (although JavaScript did not have any relationship with Java) and released Netscape 2.0 with the official support of JavaScript.
### ES1, ES2 and ES3
In 1996, Netscape decided to submit it to [ECMA International](https://en.wikipedia.org/wiki/Ecma_International) with the hopes of getting it standardized. First edition of the standard specification was released in 1997 and the language was standardized. After the initial release, `ECMAScript` was continued to be worked upon and in no-time two more versions were released ECMAScript 2 in 1998 and ECMAScript 3 in 1999.

View File

@@ -1,30 +1,8 @@
---
title: "HTTP Caching"
description: "Everything you need to know about web caching"
author:
name: "Kamran Ahmed"
url: "https://twitter.com/kamranahmedse"
imageUrl: "/authors/kamranahmedse.jpeg"
seo:
title: "HTTP Caching - roadmap.sh"
description: "Everything you need to know about web caching"
isNew: false
type: "textual"
date: 2018-11-29
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
As users, we easily get frustrated by the buffering of videos, the images that take seconds to load, and pages that got stuck because the content is being loaded. Loading the resources from some cache is much faster than fetching the same from the originating server. It reduces latency, speeds up the loading of resources, decreases the load on the server, cuts down the bandwidth costs etc.
As users, we easily get frustrated by the buffering videos, the images that take seconds to load, pages that got stuck because the content is being loaded. Loading the resources from some cache is much faster than fetching the same from the originating server. It reduces latency, speeds up the loading of resources, decreases the load on server, cuts down the bandwidth costs etc.
### Introduction
What is a web cache? It is something that sits somewhere between the client and the server, continuously looking at the requests and their responses, looking for any responses that can be cached. So that there is less time consumed when the same request is made again.
What is web cache? It is something that sits somewhere between the client and the server, continuously looking at the requests and their responses, looking for any responses that can be cached. So that there is less time consumed when the same request is made again.
![Web Cache](https://i.imgur.com/mJYVvTh.png)
@@ -33,13 +11,13 @@ What is a web cache? It is something that sits somewhere between the client and
Before we get into further details, let me give you an overview of the terms that will be used, further in the article
- **Client** could be your browser or any application requesting the server for some resource
- **Origin Server**, the source of truth, houses all the content required by the client and is responsible for fulfilling the client's requests.
- **Stale Content** is cached but expired content
- **Fresh Content** is the content available in the cache that hasn't expired yet
- **Origin Server**, the source of truth, houses all the content required by the client and is responsible for fulfilling the client requests.
- **Stale Content** is the cached but expired content
- **Fresh Content** is the content available in cache that hasn't expired yet
- **Cache Validation** is the process of contacting the server to check the validity of the cached content and get it updated for when it is going to expire
- **Cache Invalidation** is the process of removing any stale content available in the cache
![Web Cache](https://i.imgur.com/9MjlzvW.png)
![](https://i.imgur.com/9MjlzvW.png)
### Caching Locations
@@ -65,56 +43,47 @@ Unlike browser cache which serves a single user, proxy caches may serve hundreds
#### Reverse Proxy Cache
A Reverse proxy cache or surrogate cache is implemented close to the origin servers in order to reduce the load on the server. Unlike proxy caches which are implemented by ISPs etc to reduce the bandwidth usage in a network, surrogates or reverse proxy caches are implemented near the origin servers by the server administrators to reduce the load on the server.
Reverse proxy cache or surrogate cache is implemented close to the origin servers in order to reduce the load on server. Unlike proxy caches which are implemented by ISPs etc to reduce the bandwidth usage in a network, surrogates or reverse proxy caches are implemented near to the origin servers by the server administrators to reduce the load on server.
![Reverse Proxy Cache](http://i.imgur.com/Eg4Cru3.png)
Although you can control the reverse proxy caches (since it is implemented by you on your server) you can not avoid or control browser and proxy caches. And if your website is not configured to use these caches properly, it will still be cached using whatever defaults are set on these caches.
Although you can control the reverse proxy caches (since it is implemented by you on your server) you can not avoid or control browser and proxy caches. And if your website is not configured to use these caches properly, it will still be cached using whatever the defaults are set on these caches.
### Caching Headers
So, how do we control the web cache? Whenever the server emits some response, it is accompanied by some HTTP headers to guide the caches on whether and how to cache this response. The content provider is the one that has to make sure to return proper HTTP headers to force the caches on how to cache the content.
So, how do we control the web cache? Whenever the server emits some response, it is accompanied with some HTTP headers to guide the caches whether and how to cache this response. Content provider is the one that has to make sure to return proper HTTP headers to force the caches on how to cache the content.
- [Introduction](#introduction)
- [Caching Locations](#caching-locations)
- [Browser Cache](#browser-cache)
- [Proxy Cache](#proxy-cache)
- [Reverse Proxy Cache](#reverse-proxy-cache)
- [Caching Headers](#caching-headers)
- [Expires](#expires)
- [Pragma](#pragma)
- [Cache-Control](#cache-control)
- [private](#private)
- [public](#public)
- [no-store](#no-store)
- [no-cache](#no-cache)
- [max-age: seconds](#max-age-seconds)
- [s-maxage: seconds](#s-maxage-seconds)
- [must-revalidate](#must-revalidate)
- [proxy-revalidate](#proxy-revalidate)
- [Mixing Values](#mixing-values)
- [Expires](#expires)
- [Pragma](#pragma)
- [Cache-Control](#cache-control)
- [private](#private)
- [public](#public)
- [no-store](#no-store)
- [no-cache](#no-cache)
- [max-age: seconds](#max-age)
- [s-maxage: seconds](#s-maxage)
- [must-revalidate](#must-revalidate)
- [proxy-revalidate](#proxy-revalidate)
- [Mixing Values](#mixing-values)
- [Validators](#validators)
- [ETag](#etag)
- [Last-Modified](#last-modified)
- [Where do I start?](#where-do-i-start)
- [Utilizing Server](#utilizing-server)
- [Caching Recommendations](#caching-recommendations)
#### Expires
Before HTTP/1.1 and the introduction of `Cache-Control`, there was an `Expires` header which is simply a timestamp telling the caches how long should some content be considered fresh. A possible value to this header is the absolute expiry date; where a date has to be in GMT. Below is the sample header
Before HTTP/1.1 and introduction of `Cache-Control`, there was `Expires` header which is simply a timestamp telling the caches how long should some content be considered fresh. Possible value to this header is absolute expiry date; where date has to be in GMT. Below is the sample header
```html
Expires: Mon, 13 Mar 2017 12:22:00 GMT
```
It should be noted that the date cannot be more than a year and if the date format is wrong, the content will be considered stale. Also, the clock on the cache has to be in sync with the clock on the server, otherwise, the desired results might not be achieved.
It should be noted that the date cannot be more than a year and if the date format is wrong, content will be considered stale. Also, the clock on cache has to be in sync with the clock on server, otherwise the desired results might not be achieved.
Although the `Expires` header is still valid and is supported widely by the caches, preference should be given to HTTP/1.1 successor of it i.e. `Cache-Control`.
Although, `Expires` header is still valid and is supported widely by the caches, preference should be given to HTTP/1.1 successor of it i.e. `Cache-Control`.
#### Pragma
Another one from the old, pre HTTP/1.1 days, is `Pragma`. Everything that it could do is now possible using the cache-control header given below. However, one thing I would like to point out about it is, that you might see `Pragma: no-cache` being used here and there in hopes of stopping the response from being cached. It might not necessarily work; as HTTP specification discusses it in the request headers and there is no mention of it in the response headers. Rather `Cache-Control` header should be used to control the caching.
Another one from the old, pre HTTP/1.1 days, is `Pragma`. Everything that it could do is now possible using the cache-control header given below. However, one thing I would like to point out about it is, you might see `Pragma: no-cache` being used here and there in hopes of stopping the response from being cached. It might not necessarily work; as HTTP specification discusses it in the request headers and there is no mention of it in the response headers. Rather `Cache-Control` header should be used to control the caching.
#### Cache-Control
@@ -129,7 +98,7 @@ Setting the cache to `private` means that the content will not be cached in any
Cache-Control: private
```
Having said that, don't let it fool you into thinking that setting this header will make your data any secure; you still have to use SSL for that purpose.
Having said that, don't let it fool you in to thinking that setting this header will make your data any secure; you still have to use SSL for that purpose.
##### public
@@ -169,7 +138,7 @@ Cache-Control: s-maxage=3600, public
```
##### must-revalidate
**`must-revalidate`** it might happen sometimes that if you have network problems and the content cannot be retrieved from the server, the browser may serve stale content without validation. `must-revalidate` avoids that. If this directive is present, it means that stale content cannot be served in any case and the data must be re-validated from the server before serving.
**`must-revalidate`** it might happen sometimes that if you have network problems and the content cannot be retrieved from the server, browser may serve stale content without validation. `must-revalidate` avoids that. If this directive is present, it means that stale content cannot be served in any case and the data must be re-validated from the server before serving.
```html
Cache-Control: max-age=3600, public, must-revalidate
@@ -208,7 +177,7 @@ ETag: "j82j8232ha7sdh0q2882" - Strong Etag
ETag: W/"j82j8232ha7sdh0q2882" - Weak Etag (prefixed with `W/`)
```
A strong validating ETag means that two resources are **exactly** same and there is no difference between them at all. While a weak ETag means that two resources although not strictly the same but could be considered the same. Weak etags might be useful for dynamic content, for example.
A strong validating ETag means that two resources are **exactly** same and there is no difference between them at all. While a weak ETag means that two resources are although not strictly same but could be considered same. Weak etags might be useful for dynamic content, for example.
Now you know what etags are but how does the browser make this request? by making a request to server while sending the available Etag in `If-None-Match` header.

View File

@@ -1,25 +1,3 @@
---
title: "Journey to HTTP/2"
description: "The evolution of HTTP. How it all started and where we stand today"
author:
name: "Kamran Ahmed"
url: "https://twitter.com/kamranahmedse"
imageUrl: "/authors/kamranahmedse.jpeg"
seo:
title: "Journey to HTTP/2 - roadmap.sh"
description: "The evolution of HTTP. How it all started and where we stand today"
isNew: false
type: "textual"
date: 2018-12-04
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
HTTP is the protocol that every web developer should know as it powers the whole web and knowing it is definitely going to help you develop better applications. In this guide, I am going to be discussing what HTTP is, how it came to be, where it is today and how did we get here.
### What is HTTP?
@@ -93,9 +71,9 @@ Three-way handshake in its simplest form is that all the `TCP` connections begin
- `SYN ACK` - Server acknowledges the request by sending an `ACK` packet back to the client which is made up of a random number, let's say `y` picked up by server and the number `x+1` where `x` is the number that was sent by the client
- `ACK` - Client increments the number `y` received from the server and sends an `ACK` packet back with the number `y+1`
Once the three-way handshake is completed, the data sharing between the client and server may begin. It should be noted that the client may start sending the application data as soon as it dispatches the last `ACK` packet but the server will still have to wait for the `ACK` packet to be received in order to fulfill the request.
Once the three-way handshake is completed, the data sharing between the client and server may begin. It should be noted that the client may start sending the application data as soon as it dispatches the last `ACK` packet but the server will still have to wait for the `ACK` packet to be recieved in order to fulfill the request.
![Three-way Handshake](https://i.imgur.com/uERG2G2.png)
![](http://i.imgur.com/uERG2G2.png)
> Please note that there is a minor issue with the image, the last `ACK` packet sent by the client to end the handshake contains only `y+1` i.e. it should have been `ACK:y+1` instead of `ACK: x+1, y+1`
@@ -111,11 +89,11 @@ After merely 3 years of `HTTP/1.0`, the next version i.e. `HTTP/1.1` was release
- **Hostname Identification** In `HTTP/1.0` `Host` header wasn't required but `HTTP/1.1` made it required.
- **Persistent Connections** As discussed above, in `HTTP/1.0` there was only one request per connection and the connection was closed as soon as the request was fulfilled which resulted in acute performance hit and latency problems. `HTTP/1.1` introduced the persistent connections i.e. **connections weren't closed by default** and were kept open which allowed multiple sequential requests. To close the connections, the header `Connection: close` had to be available on the request. Clients usually send this header in the last request to safely close the connection.
- **Persistent Connections** As discussed above, in `HTTP/1.0` there was only one request per connection and the connection was closed as soon as the request was fulfilled which resulted in accute performance hit and latency problems. `HTTP/1.1` introduced the persistent connections i.e. **connections weren't closed by default** and were kept open which allowed multiple sequential requests. To close the connections, the header `Connection: close` had to be available on the request. Clients usually send this header in the last request to safely close the connection.
- **Pipelining** It also introduced the support for pipelining, where the client could send multiple requests to the server without waiting for the response from server on the same connection and server had to send the response in the same sequence in which requests were received. But how does the client know that this is the point where first response download completes and the content for next response starts, you may ask! Well, to solve this, there must be `Content-Length` header present which clients can use to identify where the response ends and it can start waiting for the next response.
> It should be noted that in order to benefit from persistent connections or pipelining, `Content-Length` header must be available on the response, because this would let the client know when the transmission completes and it can send the next request (in normal sequential way of sending requests) or start waiting for the next response (when pipelining is enabled).
> It should be noted that in order to benefit from persistent connections or pipelining, `Content-Length` header must be available on the response, because this would let the client know when the transmission completes and it can send the next request (in normal sequential way of sending requests) or start waiting for the the next response (when pipelining is enabled).
> But there was still an issue with this approach. And that is, what if the data is dynamic and server cannot find the content length before hand? Well in that case, you really can't benefit from persistent connections, could you?! In order to solve this `HTTP/1.1` introduced chunked encoding. In such cases server may omit content-Length in favor of chunked encoding (more to it in a moment). However, if none of them are available, then the connection must be closed at the end of request.
@@ -131,9 +109,9 @@ After merely 3 years of `HTTP/1.0`, the next version i.e. `HTTP/1.1` was release
- New status codes
- ..and more
I am not going to dwell about all the `HTTP/1.1` features in this post as it is a topic in itself and you can already find a lot about it. The one such document that I would recommend you to read is [Key differences between `HTTP/1.0` and HTTP/1.1](https://www.ra.ethz.ch/cdstore/www8/data/2136/pdf/pd1.pdf) and here is the link to [original RFC](https://tools.ietf.org/html/rfc2616) for the overachievers.
I am not going to dwell about all the `HTTP/1.1` features in this post as it is a topic in itself and you can already find a lot about it. The one such document that I would recommend you to read is [Key differences between `HTTP/1.0` and HTTP/1.1](http://www.ra.ethz.ch/cdstore/www8/data/2136/pdf/pd1.pdf) and here is the link to [original RFC](https://tools.ietf.org/html/rfc2616) for the overachievers.
`HTTP/1.1` was introduced in 1999 and it had been a standard for many years. Although, it improved alot over its predecessor; with the web changing everyday, it started to show its age. Loading a web page these days is more resource-intensive than it ever was. A simple webpage these days has to open more than 30 connections. Well `HTTP/1.1` has persistent connections, then why so many connections? you say! The reason is, in `HTTP/1.1` it can only have one outstanding connection at any moment of time. `HTTP/1.1` tried to fix this by introducing pipelining but it didn't completely address the issue because of the **head-of-line blocking** where a slow or heavy request may block the requests behind and once a request gets stuck in a pipeline, it will have to wait for the next requests to be fulfilled. To overcome these shortcomings of `HTTP/1.1`, the developers started implementing the workarounds, for example use of spritesheets, encoded images in CSS, single humongous CSS/Javascript files, [domain sharding](https://www.maxcdn.com/one/visual-glossary/domain-sharding-2/) etc.
`HTTP/1.1` was introduced in 1999 and it had been a standard for many years. Although, it improved alot over its predecessor; with the web changing everyday, it started to show its age. Loading a web page these days is more resource-intensive than it ever was. A simple webpage these days has to open more than 30 connections. Well `HTTP/1.1` has persistent connections, then why so many connections? you say! The reason is, in `HTTP/1.1` it can only have one outstanding connection at any moment of time. `HTTP/1.1` tried to fix this by introducing pipelining but it didn't completely address the issue because of the **head-of-line blocking** where a slow or heavy request may block the requests behind and once a request gets stuck in a pipeline, it will have to wait for the next requests to be fulfilled. To overcome these shortcomings of `HTTP/1.1`, the developers started implementing the workarounds, for example use of spritesheets, encoded images in CSS, single humungous CSS/Javascript files, [domain sharding](https://www.maxcdn.com/one/visual-glossary/domain-sharding-2/) etc.
### SPDY - 2009
@@ -143,7 +121,7 @@ Google went ahead and started experimenting with alternative protocols to make t
It was seen that if we keep increasing the bandwidth, the network performance increases in the beginning but a point comes when there is not much of a performance gain. But if you do the same with latency i.e. if we keep dropping the latency, there is a constant performance gain. This was the core idea for performance gain behind `SPDY`, decrease the latency to increase the network performance.
> For those who don't know the difference, latency is the delay i.e. how long it takes for data to travel between the source and destination (measured in milliseconds) and bandwidth is the amount of data transferred per second (bits per second).
> For those who don't know the difference, latency is the delay i.e. how long it takes for data to travel between the source and destination (measured in milliseconds) and bandwidth is the amount of data transfered per second (bits per second).
The features of `SPDY` included, multiplexing, compression, prioritization, security etc. I am not going to get into the details of SPDY, as you will get the idea when we get into the nitty gritty of `HTTP/2` in the next section as I said `HTTP/2` is mostly inspired from SPDY.
@@ -162,7 +140,7 @@ By now, you must be convinced that why we needed another revision of the HTTP pr
- Request Prioritization
- Security
![HTTP Model](https://i.imgur.com/S85j8gg.png)
![](http://i.imgur.com/S85j8gg.png)
#### 1. Binary Protocol
@@ -171,7 +149,7 @@ By now, you must be convinced that why we needed another revision of the HTTP pr
##### Frames and Streams
HTTP messages are now composed of one or more frames. There is a `HEADERS` frame for the meta data and `DATA` frame for the payload and there exist several other types of frames (`HEADERS`, `DATA`, `RST_STREAM`, `SETTINGS`, `PRIORITY` etc) that you can check through [the `HTTP/2` specs](https:/http2.github.iohttp2-spec/#FrameTypes).
HTTP messages are now composed of one or more frames. There is a `HEADERS` frame for the meta data and `DATA` frame for the payload and there exist several other types of frames (`HEADERS`, `DATA`, `RST_STREAM`, `SETTINGS`, `PRIORITY` etc) that you can check through [the `HTTP/2` specs](https://http2.github.io/http2-spec/#FrameTypes).
Every `HTTP/2` request and response is given a unique stream ID and it is divided into frames. Frames are nothing but binary pieces of data. A collection of frames is called a Stream. Each frame has a stream id that identifies the stream to which it belongs and each frame has a common header. Also, apart from stream ID being unique, it is worth mentioning that, any request initiated by client uses odd numbers and the response from server has even numbers stream IDs.
@@ -187,7 +165,7 @@ Since `HTTP/2` is now a binary protocol and as I said above that it uses frames
It was part of a separate RFC which was specifically aimed at optimizing the sent headers. The essence of it is that when we are constantly accessing the server from a same client there is alot of redundant data that we are sending in the headers over and over, and sometimes there might be cookies increasing the headers size which results in bandwidth usage and increased latency. To overcome this, `HTTP/2` introduced header compression.
![Header Compression](https://i.imgur.com/3IPWXvR.png)
![](http://i.imgur.com/3IPWXvR.png)
Unlike request and response, headers are not compressed in `gzip` or `compress` etc formats but there is a different mechanism in place for header compression which is literal values are encoded using Huffman code and a headers table is maintained by the client and server and both the client and server omit any repetitive headers (e.g. user agent etc) in the subsequent requests and reference them using the headers table maintained by both.
@@ -198,7 +176,7 @@ While we are talking headers, let me add here that the headers are still the sam
Server push is another tremendous feature of `HTTP/2` where the server, knowing that the client is going to ask for a certain resource, can push it to the client without even client asking for it. For example, let's say a browser loads a web page, it parses the whole page to find out the remote content that it has to load from the server and then sends consequent requests to the server to get that content.
Server push allows the server to decrease the round trips by pushing the data that it knows that client is going to demand. How it is done is, server sends a special frame called `PUSH_PROMISE` notifying the client that, "Hey, I am about to send this resource to you! Do not ask me for it." The `PUSH_PROMISE` frame is associated with the stream that caused the push to happen and it contains the promised stream ID i.e. the stream on which the server will send the resource to be pushed.
Server push allows the server to decrease the roundtrips by pushing the data that it knows that client is going to demand. How it is done is, server sends a special frame called `PUSH_PROMISE` notifying the client that, "Hey, I am about to send this resource to you! Do not ask me for it." The `PUSH_PROMISE` frame is associated with the stream that caused the push to happen and it contains the promised stream ID i.e. the stream on which the server will send the resource to be pushed.
#### 5. Request Prioritization
@@ -208,10 +186,10 @@ Without any priority information, server processes the requests asynchronously i
#### 6. Security
There was extensive discussion on whether security (through `TLS`) should be made mandatory for `HTTP/2` or not. In the end, it was decided not to make it mandatory. However, most vendors stated that they will only support `HTTP/2` when it is used over `TLS`. So, although `HTTP/2` doesn't require encryption by specs but it has kind of become mandatory by default anyway. With that out of the way, `HTTP/2` when implemented over `TLS` does impose some requirements i.e. `TLS` version `1.2` or higher must be used, there must be a certain level of minimum key sizes, ephemeral keys are required etc.
There was extensive discussion on whether security (through `TLS`) should be made mandatory for `HTTP/2` or not. In the end, it was decided not to make it mandatory. However, most vendors stated that they will only support `HTTP/2` when it is used over `TLS`. So, although `HTTP/2` doesn't require encryption by specs but it has kind of become mandatory by default anyway. With that out of the way, `HTTP/2` when implemented over `TLS` does impose some requirementsi.e. `TLS` version `1.2` or higher must be used, there must be a certain level of minimum keysizes, ephemeral keys are required etc.
`HTTP/2` is here and it has already [surpassed SPDY in adaption](https://caniuse.com/#search=http2) which is gradually increasing. `HTTP/2` has alot to offer in terms of performance gain and it is about time we should start using it.
`HTTP/2` is here and it has already [surpassed SPDY in adaption](http://caniuse.com/#search=http2) which is gradually increasing. `HTTP/2` has alot to offer in terms of performance gain and it is about time we should start using it.
For anyone interested in further details here is the [link to specs](https:/http2.github.iohttp2-spec) and a link [demonstrating the performance benefits of `HTTP/2`](https://www.http2demo.io/).
For anyone interested in further details here is the [link to specs](https://http2.github.io/http2-spec) and a link [demonstrating the performance benefits of `HTTP/2`](http://www.http2demo.io/).
And that about wraps it up. Until next time! stay tuned.

View File

@@ -0,0 +1,3 @@
[![](/guides/jwt-authentication.png)](/guides/jwt-authentication.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1273375903511465990) where this image was posted.

View File

@@ -1,25 +1,3 @@
---
title: "Levels of Seniority"
description: "How to Step Up as a Junior, Mid Level or a Senior Developer?"
author:
name: "Kamran Ahmed"
url: "https://twitter.com/kamranahmedse"
imageUrl: "/authors/kamranahmedse.jpeg"
seo:
title: "Levels of Seniority - roadmap.sh"
description: "How to Step Up as a Junior, Mid Level or a Senior Developer?"
isNew: false
type: "textual"
date: 2020-12-03
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
I have been working on redoing the [roadmaps](https://roadmap.sh) splitting the skillset based on the seniority levels to make them easier to follow and not scare the new developers away. Since the roadmaps are going to be just about the technical knowledge, I thought it would be a good idea to reiterate and have an article on what I think of different seniority roles.
I have seen many organizations decide the seniority of developers by giving more significance to the years of experience than they should. I have seen developers labeled "Junior" doing the work of Senior Developers and I have seen "Lead" developers who weren't even qualified to be called "Senior". The seniority of a developer cannot just be decided by their age, years of experience or technical knowledge that they have got. There are other factors in play here -- their perception of work, how they interact with their peers and how they approach problems. We discuss these three key factors in detail for each of the seniority levels below.

3
content/guides/oauth.md Normal file
View File

@@ -0,0 +1,3 @@
[![](/guides/oauth.png)](/guides/oauth.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1276994010423361540) where this image was posted.

View File

@@ -0,0 +1,5 @@
One of my favorite pastimes is going through the history of my favorite projects to learn how they grew over time or how certain features were implemented.
The image below describes how I do that in WebStorm.
[![](/guides/project-history.png)](/guides/project-history.png)

View File

@@ -0,0 +1,47 @@
Internet has connected people across the world using social media and audio/video calling features along with providing an overabundance of knowledge and tools. All this comes with an inherent danger of security and privacy breaches. In this guide we will talk about **proxies** which play a vital role in mitigating these risks. We will cover the following topics in this guide:
- [Proxy Server](#proxy-server)
- [Forward Proxy Server](#forward-proxy-server)
- [Reverse Proxy Server](#reverse-proxy-server)
- [Summary](#summary)
## Proxy Server
***Every web request which is sent from the client to a web server goes through some type of proxy server.*** A proxy server acts as a gateway between client *(you)* and the internet and separates end-users from the websites you browse. It replaces the source IP address of the web request with the proxy server's IP address and then forwards it to the web server. The web server is unaware of the client, it only sees the proxy server.
![Proxy Server Description](/guides/proxy/proxy-example.png)
> NOTE: This is not an accurate description rather just an illustration.
Proxy servers serve as a single point of control making it easier to enforce security policies. It also provides caching mechanism which stores the requested web pages on the proxy server to improve performance. If the requested web-page is available in cache memory then instead of forwarding the request to the web-server it will send the cached webpage back to the client. This **saves big companies thousands of dollars** by reducing load on their servers as their website is visited by millions of users every day.
## Forward Proxy Server
A forward proxy is generally implemented on the client side and **sits in front of multiple clients** or client sources. Forward proxy servers are mainly used by companies to **manage internet usage** of their employees and **restrict content**. It is also used as a **firewall** to secure company's network by blocking any request which would pose threat to the companies's network. Proxy servers are also used to **bypass geo-restriction** and browse content which might be blocked in user's country. It enables users to **browse anonymously**, as the proxy server masks their details from the website's servers.
![Forward Proxy Description](/guides/proxy/forward-proxy.png)
> NOTE: This is not an accurate description rather just an illustration
## Reverse Proxy Server
Reverse proxy servers are implemented on the **server side** instead of the client side. It **sits in front of multiple webservers** and manages the incoming requests by forwarding them to the web servers. It provides anonymity for the **back-end web servers and not the client**. Reverse proxy servers are generally used to perform tasks such as **authentication, content caching, and encryption/decryption** on behalf of the web server. These tasks would **hog CPU cycles** on the web server and degrade performance of the website by introducing high amount of delay in loading the webpage. Reverse proxies are also used as **load balancers** to distribute the incoming traffic efficiently among the web servers but it is **not optimized** for this task. In essence, reverse proxy server is a gateway to a web-server or group of web-servers.
![Reverse Proxy Description](/guides/proxy/reverse-proxy.png)
> NOTE: This is not an accurate description rather just an illustration. Red lines represent server's response and black lines represent initial request from client(s).
## Summary
A proxy server acts as a gateway between client *(you)* and the internet and separates end-users from the websites you browse. ***The position of the proxy server on the network determines whether it is a forward or a reverse proxy server***. Forward proxy is implemented on the client side and **sits in front of multiple clients** or client sources and forwards requests to the web server. Reverse proxy servers are implemented on the **server side** it **sits in front of multiple webservers** and manages the incoming requests by forwarding them to the web servers.
If all this was too much to take in, I have a simple analogy for you.
At a restaurant the waiter/waitress takes your order and gives it to the kitchen head chef. The head chef then calls out the order and assigns tasks to everyone in the kitchen.
In this analogy:
* You are the client
* Your order is the web request
* Waiter/Waitress is your forward proxy server
* Kitchen head chef is the reverse proxy server
* Other chefs working in the kitchen are the web servers
With that said our guide comes to an end. Thank you for reading and feel free to submit any updates to the guide using the links below.

View File

@@ -0,0 +1,5 @@
Random numbers are everywhere from computer games to lottery systems, graphics software, statistical sampling, computer simulation and cryptography. Graphic below is a quick explanation to how the random numbers are generated and why they may not be truly random.
[![](/guides/random-numbers.png)](/guides/random-numbers.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1237851549302312962) where this image was posted.

View File

@@ -0,0 +1,5 @@
The chart below aims to give you a really basic understanding of how the capability of a DBMS is increased to handle a growing amount of load.
[![](/guides/scaling-databases.svg)](/guides/scaling-databases.svg)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1234209674003611650) where this image was posted.

View File

@@ -0,0 +1,3 @@
[![](/guides/session-authentication.png)](/guides/session-authentication.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1264113498520465410) where this image was posted.

View File

@@ -0,0 +1,3 @@
[![](/guides/ssl-tls-https-ssh.png)](/guides/ssl-tls-https-ssh.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1252717722724642822) where this image was posted.

3
content/guides/sso.md Normal file
View File

@@ -0,0 +1,3 @@
[![](/guides/sso.png)](/guides/sso.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1280266408434302979) where this image was posted.

View File

@@ -0,0 +1,3 @@
[![](/guides/token-authentication.png)](/guides/token-authentication.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1266832006782103552) where this image was posted.

View File

@@ -1,25 +1,3 @@
---
title: "Building a BitTorrent Client"
description: "Learn everything you need to know about BitTorrent by writing a client in Go"
author:
name: "Jesse Li"
url: "https://twitter.com/__jesse_li"
imageUrl: "/authors/jesse.png"
seo:
title: "Building a BitTorrent Client - roadmap.sh"
description: "Learn everything you need to know about BitTorrent by writing a client in Go"
isNew: false
type: "textual"
date: 2021-01-17
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
BitTorrent is a protocol for downloading and distributing files across the Internet. In contrast with the traditional client/server relationship, in which downloaders connect to a central server (for example: watching a movie on Netflix, or loading the web page you're reading now), participants in the BitTorrent network, called **peers**, download pieces of files from *each other*—this is what makes it a **peer-to-peer** protocol. In this article we will investigate how this works, and build our own client that can find peers and exchange data between them.
![diagram showing the difference between client/server (all clients connecting to one server) and peer-to-peer (peers connecting to each other) relationships](/guides/torrent-client/client-server-p2p.png)
@@ -497,7 +475,7 @@ Files, pieces, and piece hashes aren't the full story—we can go further by bre
A peer is supposed to sever the connection if they receive a request for a block larger than 16KB. However, based on my experience, they're often perfectly happy to satisfy requests up to 128KB. I only got moderate gains in overall speed with larger block sizes, so it's probably better to stick with the spec.
#### Pipelining
Network round-trips are expensive, and requesting each block one by one will absolutely thank the performance of our download. Therefore, it's important to **pipeline** our requests such that we keep up a constant pressure of some number of unfulfilled requests. This can increase the throughput of our connection by an order of magnitude.
Network round-trips are expensive, and requesting each block one by one will absolutely tank the performance of our download. Therefore, it's important to **pipeline** our requests such that we keep up a constant pressure of some number of unfulfilled requests. This can increase the throughput of our connection by an order of magnitude.
![Two email threads simulating peer connections. The thread on the left shows a request followed by a reply, repeated three times. The thread on the left sends three requests, and receives three replies in quick succession.](/guides/torrent-client/pipelining.png)

View File

@@ -0,0 +1,3 @@
[![](/guides/unfamiliar-codebase.png)](/guides/unfamiliar-codebase.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1256340163573231616) where this image was posted.

View File

@@ -0,0 +1,11 @@
> **Roadmap is not ready yet**. Please check back later or [subscribe to get notified](/signup).
While we prepare the roadmap, follow this simple advice to learn anything
> Just **pick a project and start working on it**, you will learn all that you need along the way.
**&rarr;** &nbsp; [All Roadmaps](/roadmaps) &nbsp;&bull;&nbsp; [Programming guides](/guides) &nbsp;&bull;&nbsp; [Subscribe](/signup)

View File

@@ -0,0 +1,3 @@
[![](/guides/web-vitals.png)](/guides/web-vitals.png)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1425476526770987012) where this image was posted.

View File

@@ -0,0 +1,62 @@
Since the explosive growth of web-based applications, every developer could stand to benefit from understanding how the Internet works. In this article, accompanied with an introductory series of short videos about the Internet from [code.org](https://code.org), you will learn the basics of the Internet and how it works. After going through this article, you will be able to answer the below questions:
* What is the Internet?
* How does the information move on the internet?
* How do the networks talk to each other and the protocols involved?
* What's the relationship between packets, routers, and reliability?
* HTTP and the HTML How are you viewing this webpage in your browser?
* How is the information transfer on the internet made secure?
* What is cybersecurity and what are some common internet crimes?
## What is the Internet?
The Internet is a global network of computers connected to each other which communicate through a standardized set of protocols.
In the video below, Vint Cerf, one of the "fathers of the internet," explains the history of how the Internet works and how no one person or organization is really in charge of it.
<iframe width="100%" height="400" src="https://www.youtube.com/embed/Dxcc6ycZ73M" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Wires, Cables, and Wi-Fi
Information on the Internet moves from computer to another in the form of bits over various mediums, including Ethernet cables, fiber optic cables, and wireless signals (i.e., radio waves).
In the video linked below, you will learn about the different mediums for data transfer on the Internet and the pros and cons for each.
<iframe width="100%" height="400" src="https://www.youtube.com/embed/ZhEf7e4kopM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## IP Addresses and DNS
Now that you know about the physical medium for the data transfer over the internet, it's time to learn about the protocols involved. How does the information traverse from one computer to another in this massive global network of computers?
In the video below, you will get a brief introduction to IP, DNS, and how these protocols make the Internet work.
<iframe width="100%" height="400" src="https://www.youtube.com/embed/5o8CwafCxnU" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Packets, Routing, and Reliability
Information transfer on the Internet from one computer to another does not need to follow a fixed path; in fact, it may change paths during the transfer. This information transfer is done in the form of packets and these packets may follow different routes depending on certain factors.
In this video, you will learn about how the packets of information are routed from one computer to another to reach the destination.
<iframe width="100%" height="400" src="https://www.youtube.com/embed/AYdF7b3nMto" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## HTTP and HTML
HTTP is the standard protocol by which webpages are transferred over the Internet. The video below is a brief introduction to HTTP and how web browsers load websites for you.
<iframe width="100%" height="400" src="https://www.youtube.com/embed/kBXQZMmiA4s" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Encryption and Public Keys
Cryptography is what keeps our communication secure on the Internet. In this short video, you will learn the basics of cryptograpy, SSL/TLS, and how they help make the communication on the Internet secure.
<iframe width="100%" height="400" src="https://www.youtube.com/embed/ZghMPWGXexs" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## Cybersecurity and Crime
In this video, you will learn about the basics of cybersecurity and common cybercrimes
<iframe width="100%" height="400" src="https://www.youtube.com/embed/AuYNXgO_f3Y" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
And that wraps it up for this article. To learn more about the Internet, [Kamran Ahmed](https://twitter.com/kamranahmedse) has a nice little guide on [DNS: How a website is found on the Internet](/guides/dns-in-one-picture). Also, go through the episodes of [howdns.works](https://howdns.works/) and read this [cartoon intro to DNS over HTTPS](https://hacks.mozilla.org/2018/05/a-cartoon-intro-to-dns-over-https/).

View File

@@ -0,0 +1,3 @@
[![](/guides/sli-slo-sla.jpeg)](/guides/sli-slo-sla.jpeg)
Here is the [original tweet](https://twitter.com/kamranahmedse/status/1421778722865229824) where this image was posted.

View File

@@ -1,52 +1,30 @@
---
title: "Build it and they will come?"
description: "Why “build it and they will come” alone wont work anymore"
author:
name: "Peter Thaleikis"
url: "https://twitter.com/spekulatius1984"
imageUrl: "/authors/spekulatius.jpg"
seo:
title: "Build it and they will come? - roadmap.sh"
description: "Why “build it and they will come” alone wont work anymore"
isNew: false
type: "textual"
date: 2021-05-04
sitemap:
priority: 0.7
changefreq: "weekly"
tags:
- "guide"
- "textual-guide"
- "guide-sitemap"
---
We all have heard the mantra *"build it and they will come"* many times. Stories of people building a startup or project and seemingly stumbling upon a goldmine aren't few, but they aren't the rule. These stories are still the exception in the mass of launched projects and startups.
Before the [Wright brothers](https://en.wikipedia.org/wiki/Wright_brothers) built their Kitty Hawk, people generally believed heavy objects could not fly - physics simply forbade it. The idea of regularly boarding airplanes as we do it these days was unthinkable. It was considered an unrealistic daydream for humans to ever claim the sky. When the first airplanes took off, people were fascinated, of course. It was a topic people continued to talk about for ages. Technology had made something impossible possible. While the wording "build it and they will come" originated from the movie [Field of Dreams](https://en.wikipedia.org/wiki/Field_of_Dreams), this and similar historic events gave birth to the idea behind it.
Before the [Wright brothers](https://en.wikipedia.org/wiki/Wright_brothers) built their Kitty Hawk, people generally believed heavy objects could not fly - physics simply forbade it. The idea to regularly board airplanes as we do it these days was unthinkable. It was considered an unrealistic daydream for humans to ever claim the sky. When the first airplanes took off, people were fascinated, of course. It was a topic people continued to talk about for ages. Technology had made something impossible possible. While the wording "build it and they will come" originated from the movie [Field of Dreams](https://en.wikipedia.org/wiki/Field_of_Dreams), this and similar historic events gave birth to the idea behind it.
The engineers' and inventors' dreams came true: spend time doing what you love while success follows magically. The internet and web-standards democratized access to this dream. But with it, the idea behind it faded and became less and less powerful. In 2020, there are very strong signs the popular saying isn't correct anymore.
The engineers' and inventors' dreams came true: spend time doing what you love while the success follows magically. The internet and web-standards democratized access to this dream. But with it, the idea behind it faded and became less and less powerful. In 2020, there are very strong signs the popular saying isn't correct anymore.
Why doesn't "build it and they will come" work anymore?
-------------------------------------------------------
There are a few reasons for working hard to make "build it and they will come" a thing of the past. This being said, it doesn't mean you can't succeed in building a side-project anymore. You've just got to adjust the way you are building it.
There are a few reasons working hard to make "build it and they will come" a thing of the past. This being said, it doesn't mean you can't succeed building a side-project anymore. You've just got to adjust the way you are building it.
### Building got much easier
As a software engineer, some websites are a blessing. Most of us couldn't work without GitHub, Stackoverflow and of course Google, ahem, DuckDuckGo. These powerful sites help us to solve problems, learn new techniques and find the right libraries to make building projects easier. If any of these sites are down, most engineers take a break and go for a coffee instead of trying to continue working. Combine this with more sophisticated web-standards and easier access to tooling, and you arrive at a world where building projects isn't just a job for highly specialist developers anymore. Powerful frameworks such as [Laravel](https://laravel.com/) and [Quasar Framework](https://quasar.dev/) are available for anyone to build projects on - for free.
In fact, building projects got to a point where some people simply build them as an exercise or hobby. If you spend some time browsing GitHub you will be surprised by the open source projects people built without any commercial goals. "Low code" and "No code" are the next wave of people building projects with a less technological background.
In fact, building projects got to a point where some people simply build them as an exercise or hobby. If you spend some time browsing GitHub you will be surprised by the open source projects people built without any commercial goals. "Low code" and "No code" are the next wave of people building projects with less technological background.
### Too much going on: information overload
We are living in a world with information overload. In the online sphere, you can find a lot of useful information. But there is also a lot of noise. For each piece of information or advice, you can find a number of opposing statements. This is partly due to the fact that the internet made it much easier to publish and share information. Everyone has been given a voice - for good or bad. This makes it much harder to reach potential users. Your new project probably just drowns amongst kitten videos, opinions, and news. Never has the average lifetime of published content been so low. You've got to come up with a marketing plan before setting out on the journey.
We are living in a world with information overload. In the online sphere, you can find a lot of useful information. But there is also a lot of noise. For each piece of information or advice you can find a number of opposing statements. This is partly due to the fact that the internet made it much easier to publish and share information. Everyone has been given a voice - for good or bad. This makes it much harder to reach potential users. Your new project probably just drowns amongst kitten videos, opinions, and news. Never has the average lifetime of published content been so low. You've got to come up with a marketing plan before setting out on the journey.
### Smaller Problems
Besides building is easier than ever before and attention is in short supply, there is another issue making the life of makers, inventors, and engineers harder: today's problems are much smaller. Back when the previously mentioned Wright Brothers set out, they fascinated people with the problem they were aiming to address: flying. Unless your name is Elon, your problem is unlikely to attract many people naturally. As a solo developer or indie hacker, the chances are higher of having a much smaller problem in a niche (of a niche). With the information overload mentioned before, niches are pretty much the only way to build a side-project or startup and succeed.
Besides building being easier than ever before and attention being in short supply, there is another issue making the life of makers, inventors and engineers harder: today's problems are much smaller. Back when the previously mentioned Wright Brothers set out, they fascinated people with the problem they were aiming to address: flying. Unless your name is Elon, your problem is unlikely to attract many people naturally. As a solo developer or indie hacker, the chances are higher for having a much smaller problem in a niche (of a niche). With the information overload mentioned before, niches are pretty much the only way to build a side-project or startup and succeed.
Does sound pretty grim for inventors, developers, and engineers? Well, yes and no. We've got to tweak the approach to get in front of the eye of potential users and customers.
Does sound pretty grim for inventors, developers and engineers? Well, yes and no. We've got to tweak the approach to get in front of the eye of potential users and customers.
How to market your project nowadays?
@@ -56,27 +34,27 @@ The very first step to improving the odds of success is [idea validation](https:
### Build your Audience first and the project after.
Build your audience before you build your project. Spend your time connecting with potential users, learning from their needs, and talking about their problems. This will help you market your project later on. The audience first, projects second. There are numerous ways to build an audience. One of the simplest and easiest is to start with a personal or [project blog](https://startupnamecheck.com/blog/how-to-start-a-small-business-blog).
Build your audience before you build your project. Spend your time connecting with potential users, learn from their needs and talk about their problems. This will help you market your project later on. Audience first, project second. There are numerous ways to build an audience. One of the simplest and easiest is to start with a personal or [project blog](https://startupnamecheck.com/blog/how-to-start-a-small-business-blog).
Don't use Medium or a similar service - opt for a self-hosted blog as it allows you to build the blog freely to your needs and have decent links back to your project later on. Don't forget to add a newsletter. Newsletters are a key to reconnecting in our world of short attention spans.
Don't use Medium or a similar service - opt for a self-hosted blog as it allows you to build the blog freely to your needs and have decent links back to your project later on. Don't forget to add a newsletter. Newsletters are a key to reconnect in our world of short attention spans.
### Tool by Tool
Another approach is the "Tool by Tool" approach. I first noticed this approach being used by Shopify. The team at Shopify is providing little tools such as a [logo generator](https://hatchful.shopify.com/) and releasing these tools free for anyone to use. This not just builds goodwill with people; it also allows Shopify to attract powerful backlinks to their projects. As developers, we are in the perfect position to build such mini-tools. It boosts morale and drives attention at the same time.
Another approach is the "Tool by Tool" approach. I've first noticed this approach being used by Shopify. The team at Shopify are providing little tools such as a [logo generator](https://hatchful.shopify.com/) and release these tools free for anyone to use. This not just builds goodwill with people; it also allows Shopify to attract powerful backlinks to their projects. As developers we are in the perfect position to build such mini-tools. It boosts morale and drives attention at the same time.
Spend some time evaluating where your project or product will deliver value to the end-user. Look at options to split off small, independent tools. Build these and launch them before launching the whole product. This allows you to practice launching and promoting your part-projects at the same time. With each backlink to your part-projects, you will enhance your ranking in Google. An example of a maker following this approach is [Kamban](https://kambanthemaker.com/) with [FlatGA](https://flatga.io/). He built FlatGA as phase one of a bigger project currently in development.
Spend some time evaluating where your project or product will deliver value to the end-user. Look at options to split off small, independent tools. Build these and launch them before launching the whole product. This allows you to practice launching and promoting your part-projects at the same time. With each backlink to your part-projects you will enhance your ranking in Google. An example for a maker following this approach is [Kamban](https://kambanthemaker.com/) with [FlatGA](https://flatga.io/). He built FlatGA as phase one of a bigger project currently in development.
### Join a Maker community
While you are building your part-projects, don't forget to discuss the progress publicly. This helps to attract an audience around your work and makes the launches easier. You can use Twitter threads and Reddit posts to share updates. A maker community such as [makerlog](https://getmakerlog.com/) or [WIP.chat](https://wip.chat) can also extend your reach. These allow you to get instant feedback, and keep yourself accountable and they will enhance your reach at the same time.
While you are building your part-projects, don't forget to discuss the progress publicly. This helps to attract an audience around your work and makes the launches easier. You can use Twitter threads and Reddit posts to share updates. A maker community such as [makerlog](https://getmakerlog.com/) or [WIP.chat](https://wip.chat) can also extend your reach. These allow you to get instant feedback, keep yourself accountable and they will enhance your reach at the same time.
### Getting ready to Launch
Launching seems like this special moment when you release your project into the wide world. Often this moment is combined with high expectations and developers consider launching their project the key - if not only - part of their approach to marketing. While launching can help to attract some initial customers, it shouldn't be your only idea when it comes to marketing. You should also know that launching isn't a single event. You can (and should) launch again and again. Every time you launch you are increasing the chance to reach more new customers. After the launch is before the launch.
Launching seems like this special moment when you release your project into the wide world. Often this moment is combined with high expectations and developers consider launching their project the key - if not only - part of their approach to marketing. While launching can help to attract some initial customers, it shouldn't be your only idea when it comes to marketing. You should also know that launching isn't a single event. You can (and should) launch again and again. Every time you launch you are increasing the chance to reach more and new customers. After the launch is before the launch.
### Marketing Is an On-going Fight
Many developers plan to launch their product on a few sites and see where it takes their project from there on. This works well if your product goes viral by luck. A much more sustainable approach is constantly working a little on it. Marketing is most effective if done consistently. That holds true for blogging as well as most other forms of marketing. A simple approach to keep you on the path to marketing your project regularly is subscribing to a free [newsletter with small marketing opportunities](https://wheretopost.email). This way, you are regularly reminded and given bite-sized tasks to complete.
Many developers plan to launch their product on a few sites and see where it takes their project from there on. This works well, if your product goes viral by luck. A much more sustainable approach is constantly working a little on it. Marketing is most effective, if done consistently. That holds true for blogging as well as most other forms of marketing. A simple approach to keep you on the path to market your project regularly is subscribing to a free [newsletter with small marketing opportunities](https://wheretopost.email). This way, you are regularly reminded and given bite-sized tasks to complete.
Closing Words
@@ -88,4 +66,4 @@ I hope the article helped you to wrap your head around the idea that building si
About the author
----------------
[Peter Thaleikis](https://peterthaleikis.com/) a software engineer and business owner. He has been developing web applications since around 2000. Before he started his own software development company [Bring Your Own Ideas Ltd.](https://bringyourownideas.com/), he has been a Lead Developer for multiple organizations.
[Peter Thaleikis](https://peterthaleikis.com/) a software engineer and business owner. He has been developing web applications since around 2000. Before he started his own software development company [Bring Your Own Ideas Ltd.](https://bringyourownideas.com/), he has been Lead Developer for multiple organisations.

67
content/pages/about.md Normal file
View File

@@ -0,0 +1,67 @@
## What is roadmap.sh?
Roadmap.sh is the place containing community curated roadmaps, study plans, paths and resources for the budding
developers. It started as a [set of charts to guide the developers](https://github.com/kamranahmedse/developer-roadmap)
who are confused about what should they learn next but that alone wasn't enough so I expanded it into the website to get
more contributors involved.
## What are the plans for roadmap.sh?
The website started off as
a [simple repository containing a few charts](https://github.com/kamranahmedse/developer-roadmap) for developers and
based on my personal opinions but it could have been much more than that so I decided to expand it to a website where
people can contribute to study plans with their areas of expertise as well, add more roadmaps, write guides etc.
We haven't opened up the sign ups for now but we will be doing. My long term plans for this website are to turn it into
a goto place for the developers to seek guidance about their careers, help others, share their journeys, incentivize the
learnings, get feedbacks on their projects etc.
## How did you build roadmap.sh?
The basic version of the website has been built with [Next.js](https://github.com/zeit/next.js/), is opensource and can
be found on [github](https://github.com/kamranahmedse/roadmap.sh). It was hastily done to get it out in front of the
people and get people to start contributing so it might be rough on the edges, but that is where we need your help.
## How does it make money?
It doesn't make any money. I have been using my personal time and budget to build it. I did not create this website with
any intentions of monetization but as a good will, to help the people get out of the frustration that I was once in.
Having said that, I love teaching and my future plans are to be able to work full-time on roadmap.sh for which it has to
make enough money to pay for my rent, groceries, bills, travel expenses, etc but even if it doesn't it's likely I'll
continue growing the site however I can. My focus at the moment is not making money from it and just add content that
creates value for the people.
> Sponsor the efforts by [paying as little as 5$ per month](https://github.com/sponsors/kamranahmedse) or with [one time payment via paypal](https://paypal.me/kamranahmedse). Alternatively, reach out to me at [kamranahmed.se@gmail.com](mailto:kamranahmed.se@gmail.com).
## Can I contribute?
You definitely can, infact you are encouraged to do that. Even your minor contributions such as typo fixes count. The
source code of the website can be [found on Github](https://github.com/kamranahmedse/roadmap.sh). Your contributions can
be:
* Adding a new roadmap
* Updating existing roadmap
* Suggesting changes to the existing roadmaps
* Writing a Guide
* Updating an existing guide
* Fixing grammar mistakes, typos on the website or the content
* Updating the UI of the website
* Refactoring the codebase
* Becoming a sponsor
Just make sure
to [follow the contribution guidelines](https://github.com/kamranahmedse/roadmap.sh/tree/master/contributing) when you
decide to contribute.
## Can I redistribute the content?
No, the license of the content on this website does not allow you to redistribute any of the content on this website
anywhere. You can use it for personal use or share the link to the content if you have to but redistribution is not
allowed.
## What is the best way to contact you?
Tweet or send me a message [@kamranahmedse](https://twitter.com/kamranahmedse) or email me
at [kamranahmed.se@gmail.com](mailto:kamranahmed.se@gmail.com). I get lots of messages so apologies in advance if you don't hear back
from me soon but I do reply to everyone.

View File

@@ -1,9 +1,3 @@
---
layout: ../layouts/MarkdownLayout.astro
title: Privacy Policy - roadmap.sh
noIndex: true
---
# Privacy Policy
By using or accessing the Services in any manner, you acknowledge that you accept the practices and policies outlined in this Privacy Policy, and you hereby consent that we will collect, use, and share your information in the following ways. Remember that your use of roadmap.shs Services is at all times subject to the [Terms of Use](/terms), which incorporates this Privacy Policy. Any terms we use in this Policy without defining them have the definitions given to them in the Terms of Use.
@@ -78,3 +72,7 @@ You may be able to add, update, or delete information as explained above. When y
## What if I have questions about this policy?
If you have any questions or concerns regarding our privacy policies, please send us a detailed message to kamranahmed.se@gmail.com, and we will try to resolve your concerns.

View File

@@ -1,9 +1,3 @@
---
layout: ../layouts/MarkdownLayout.astro
title: Terms and Conditions - roadmap.sh
noIndex: true
---
# Terms of Service
PLEASE NOTE THAT YOUR USE OF AND ACCESS TO OUR SERVICES (DEFINED BELOW) ARE SUBJECT TO THE FOLLOWING TERMS; IF YOU DO NOT AGREE TO ALL OF THE FOLLOWING, YOU MAY NOT USE OR ACCESS THE SERVICES IN ANY MANNER.
@@ -22,7 +16,7 @@ Except for changes by us as described here, no other amendment or modification o
## Do these terms cover privacy?
You can view the current roadmap.sh [Privacy Policy here](/privacy).
You can view the current roadmap.sh Privacy Policy [here](/privacy).
The Childrens Online Privacy Protection Act (“COPPA”) requires that online service providers obtain parental consent before they knowingly collect personally identifiable information online from children who are under 13. We do not knowingly collect or solicit personally identifiable information from children under 13. If you are a child under 13, please do not attempt to register for the Services or send any personal information about yourself to us. If we learn we have collected personal information from a child under 13, we will delete that information as quickly as possible. If you believe that a child under 13 may have provided us personal information, please contact us at kamranahmed.se@gmail.com.
@@ -127,3 +121,5 @@ Choice of Law; Arbitration. These Terms are governed by and will be construed un
Miscellaneous. You will be responsible for paying, withholding, filing, and reporting all taxes, duties, and other governmental assessments associated with your activity in connection with the Services, provided that roadmap.sh may, in its sole discretion, do any of the foregoing on your behalf or for itself as it sees fit. The failure of either you or us to exercise, in any way, any right herein shall not be deemed a waiver of any further rights hereunder. If any provision of these Terms is found to be unenforceable or invalid, that provision will be limited or eliminated, to the minimum extent necessary, so that these Terms shall otherwise remain in full force and effect and enforceable. You and roadmap.sh agree that these Terms are the complete and exclusive statement of the mutual understanding between you and roadmap.sh, and that it supersedes and cancels all previous written and oral agreements, communications and other understandings relating to the subject matter of these Terms. You hereby acknowledge and agree that you are not an employee, agent, partner, or joint venture of roadmap.sh, and you do not have any authority of any kind to bind roadmap.sh in any respect whatsoever. Except as expressly set forth in the section above regarding the Apple Application, you and roadmap.sh agree there are no third party beneficiaries intended under these Terms.

288
content/roadmaps.json Normal file
View File

@@ -0,0 +1,288 @@
[
{
"seo": {
"title": "Learn to become a modern frontend developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern frontend development. Learn to become a modern frontend developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"frontend roadmap",
"javascript roadmap",
"frontend roadmap 2021",
"javascript roadmap 2021",
"guide to becoming a developer",
"guide to becoming a frontend developer",
"frontend developer",
"frontend engineer",
"frontend skills",
"frontend development",
"javascript developer",
"frontend development skills",
"frontend development skills test",
"frontend engineer roadmap",
"frontend developer roadmap",
"become a frontend developer",
"frontend developer career path",
"javascript developer",
"modern javascript developer",
"node developer",
"skills for frontend development",
"learn frontend development",
"what is frontend development",
"frontend developer quiz",
"frontend developer interview questions"
]
},
"title": "Frontend Developer",
"description": "Step by step guide to becoming a modern frontend developer in 2021",
"featuredTitle": "Frontend",
"featuredDescription": "Step by step guide to becoming a frontend developer in 2021",
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"featured": true,
"imagePath": "/roadmaps/frontend.png",
"resourcesPath": "/roadmaps/1-frontend/resources.md",
"pdfUrl": "https://kamranahmedse.gumroad.com/l/frontend-roadmap",
"id": "frontend",
"isUpcoming": false
},
{
"seo": {
"title": "Learn to become a modern backend developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern backend development. Learn to become a modern backend developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a developer",
"guide to becoming a backend developer",
"backend developer",
"backend engineer",
"backend skills",
"backend development",
"javascript developer",
"backend development skills",
"backend development skills test",
"backend engineer roadmap",
"backend developer roadmap",
"become a backend developer",
"backend developer career path",
"javascript developer",
"modern javascript developer",
"node developer",
"skills for backend development",
"learn backend development",
"what is backend development",
"backend developer quiz",
"backend developer interview questions"
]
},
"title": "Backend Developer",
"description": "Step by step guide to becoming a modern backend developer in 2021",
"featuredTitle": "Backend",
"featuredDescription": "Step by step guide to becoming a backend developer in 2021",
"featured": true,
"imagePath": "/roadmaps/backend.png",
"resourcesPath": "/roadmaps/2-backend/resources.md",
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"pdfUrl": "https://kamranahmedse.gumroad.com/l/backend-roadmap",
"id": "backend",
"isUpcoming": false
},
{
"seo": {
"title": "DevOps Roadmap: Learn to become a DevOps Engineer or SRE",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for DevOps. Learn to become a modern DevOps engineer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a devops enginer",
"devops roadmap",
"sre roadmap",
"site reliability engineer roadmap",
"operations roles",
"become devops",
"devops skills",
"modern devops skills",
"devops skills test",
"skills for devops",
"learn devops",
"what is devops",
"what is sre",
"devops quiz",
"devops interview questions"
]
},
"title": "DevOps Roadmap",
"description": "Step by step guide for DevOps, SRE or any other Operations Role in 2021",
"featuredTitle": "DevOps",
"featuredDescription": "Step by step guide for DevOps or operations role in 2021",
"featured": true,
"imagePath": "/roadmaps/devops.png",
"resourcesPath": "/roadmaps/3-devops/resources.md",
"versions": [
"latest",
"2018",
"2017"
],
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"pdfUrl": "https://kamranahmedse.gumroad.com/l/devops-roadmap",
"id": "devops",
"isUpcoming": false
},
{
"seo": {
"title": "React Developer Roadmap: Learn to become a React developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for react development. Learn to become a modern React developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a react developer",
"react developer roadmap",
"react roadmap",
"become react developer",
"react developer skills",
"react skills test",
"skills for react development",
"learn react development",
"what is react",
"react quiz",
"react interview questions"
]
},
"title": "React Developer",
"description": "Everything that is there to learn about React and the ecosystem in 2021.",
"featuredTitle": "React",
"featuredDescription": "Step by step guide to become a React Developer in 2021",
"isTextHeavy": false,
"isCommunity": false,
"featured": true,
"contentPath": "/roadmaps/4-react/landscape.md",
"resourcesPath": "/roadmaps/4-react/resources.md",
"versions": [
"latest",
"2018",
"2017"
],
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"pdfUrl": "https://kamranahmedse.gumroad.com/l/react-roadmap",
"id": "react",
"isUpcoming": false
},
{
"seo": {
"title": "DBA Roadmap: Learn to become a database administrator with PostgreSQL",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for DevOps. Learn to become a modern DevOps engineer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a database administrator",
"guide to becoming a DBA",
"dba roadmap",
"db administrator roadmap",
"database administrator roadmap",
"postgresql roadmap",
"dba skills",
"db administrator skills",
"become dba",
"postgresql skills",
"modern dba skills",
"dba skills test",
"skills for dba",
"skills for database administrator",
"learn dba",
"what is dba",
"database administrator quiz",
"dba interview questions"
]
},
"title": "PostgreSQL DBA",
"description": "Step by step guide to becoming a modern PostgreSQL DB Administrator in 2021",
"featuredTitle": "DBA",
"featuredDescription": "Step by step guide to become a PostgreSQL DBA in 2021",
"contentPath": "/roadmaps/5-postgresql-dba/landscape.md",
"resourcesPath": "/roadmaps/5-postgresql-dba/resources.md",
"author": {
"name": "Alexey Lesovsky",
"url": "https://github.com/lesovsky"
},
"isCommunity": true,
"isTextHeavy": true,
"featured": true,
"detailed": false,
"versions": [],
"id": "postgresql-dba",
"isUpcoming": false
},
{
"seo": {
"title": "Android Developer Roadmap: Learn to become an Android developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for android development. Learn to become a modern Android developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming an android developer",
"android developer roadmap",
"android roadmap",
"become android developer",
"android developer skills",
"android skills test",
"skills for android development",
"learn android development",
"what is android",
"android quiz",
"android interview questions"
]
},
"title": "Android Developer",
"description": "Step by step guide to becoming an Android developer in 2021",
"featuredTitle": "Android",
"featuredDescription": "Step by step guide to becoming an Android Developer in 2021",
"isTextHeavy": true,
"isCommunity": true,
"featured": true,
"contentPath": "/roadmaps/6-android/landscape.md",
"resourcesPath": "/roadmaps/6-android/resources.md",
"versions": [
"latest",
"2018",
"2017"
],
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"id": "android",
"isUpcoming": false
},
{
"seo": {
"title": "QA Roadmap: Learn to become a modern QA engineer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern QA development. Learn to become a modern QA engineer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a QA engineer",
"QA engineer",
"QA skills",
"QA development skills",
"QA development skills test",
"QA engineer roadmap",
"become a QA engineer",
"QA engineer career path",
"skills for QA development",
"what is QA engineer",
"QA engineer quiz",
"QA engineer interview questions"
]
},
"title": "QA Engineer",
"description": "Steps to follow in order to become a modern QA Engineer in 2021",
"featuredTitle": "QA",
"featuredDescription": "Step by step guide to becoming a modern QA Engineer in 2021",
"isUpcoming": true,
"contentPath": "/roadmaps/7-qa/landscape.md",
"resourcesPath": "/roadmaps/7-qa/resources.md",
"author": {
"name": "Anas Fitiani",
"url": "https://github.com/anas-qa"
},
"id": "qa"
}
]

View File

@@ -0,0 +1,41 @@
{
"seo": {
"title": "Learn to become a modern frontend developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern frontend development. Learn to become a modern frontend developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a developer",
"guide to becoming a frontend developer",
"frontend developer",
"frontend engineer",
"frontend skills",
"frontend development",
"javascript developer",
"frontend development skills",
"frontend development skills test",
"frontend engineer roadmap",
"frontend developer roadmap",
"become a frontend developer",
"frontend developer career path",
"javascript developer",
"modern javascript developer",
"node developer",
"skills for frontend development",
"learn frontend development",
"what is frontend development",
"frontend developer quiz",
"frontend developer interview questions"
]
},
"title": "Frontend Developer",
"description": "Step by step guide to becoming a modern frontend developer in 2021",
"featuredTitle": "Frontend",
"featuredDescription": "Step by step guide to becoming a frontend developer in 2021",
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"featured": true,
"imagePath": "/roadmaps/frontend.png",
"resourcesPath": "./resources.md",
"pdfUrl": "https://kamranahmedse.gumroad.com/l/frontend-roadmap"
}

View File

@@ -0,0 +1,76 @@
<div className='alert alert-primary' style={{ marginBottom: '-10px'}}>
This page is incomplete and is being worked upon. Please check back later or <a href='/signup'>subscribe</a> / <a href='https://twitter.com/kamranahmedse'>follow me on twitter</a> to get notified. Also, feel free to contribute by suggesting the resources in <a href='https://github.com/kamranahmedse/developer-roadmap'>the issues</a>.
</div>
# Become a Frontend Developer
Before I go ahead and list down the resources, please know that the roadmap and the list below is exhaustive and you don't need to know it all from the get go. For frontend development, all you need to get started with is learn some basic HTML, CSS and JavaScript and start working on projects; everything else you will learn along the way.
## Internet and how it works?
Get the basic understanding of internet, browsers, networks and other relevant knowledge.
* <BadgeLink badgeText='Read' href='/guides/what-is-internet'>What is Internet?</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=7_LPdttKXPc'>How the internet works in 5 minutes</BadgeLink>
* <BadgeLink badgeText='Read' href='https://kamranahmed.info/blog/2016/08/13/http-in-depth/'>What is HTTP and how it evolved?</BadgeLink>
* <BadgeLink badgeText='Read' href='https://blog.cloudflare.com/http3-the-past-present-and-future/'>HTTP/3: the past, the present, and the future</BadgeLink>
* <BadgeLink badgeText='Read' href='https://kinsta.com/blog/http3/'>What Is HTTP/3 Lowdown on the Fast New UDP-Based Protocol</BadgeLink>
* <BadgeLink badgeText='Read' href='https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/'>How Browsers Work: Behind the scenes of modern web browsers</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=Rck3BALhI5c'>DNS as Fast As Possible</BadgeLink>
* <BadgeLink badgeText='Read' href='https://howdns.works/'>How DNS works?</BadgeLink>
* <BadgeLink badgeText='Read' href='/guides/dns-in-one-picture'>DNS in One Picture</BadgeLink>
## Learn HTML
HTML provides the skeleton of a webpage. Learn the basics of HTML; learn the basic tags, learn how to write semantic HTML, understand basic SEO, learn how to divide your pages into sections that will help you style them.
Please know that I have put multiple links for each resource. While you may pick something new while going through each, you don't need to go through all of them - if you feel like you have understood the concepts and are just repeating what you learnt, you may skip the resource and move to exercises section.
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=UB1O30fR-EE'>HTML Crash Course For Absolute Beginners</BadgeLink>
* <BadgeLink badgeText='Read' href='https://www.w3schools.com/html/default.asp'>W3Schools HTML Tutorial</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=pQN-pnXPaVg'>HTML Full Course - Build a Website Tutorial</BadgeLink>
* <BadgeLink badgeText='Read' href='https://hacks.mozilla.org/2016/08/a-few-html-tips/'>A few HTML tips</BadgeLink>
* <BadgeLink badgeText='Read' href='https://hackernoon.com/six-tips-to-set-up-a-better-html-document-ud1033z3z'>Six tips to set up a better HTML document</BadgeLink>
* <BadgeLink badgeText='Read' href='https://www.w3schools.com/html/html5_semantic_elements.asp'>HTML Semantic Elements</BadgeLink>
* <BadgeLink badgeText='Read' href='https://developer.mozilla.org/en-US/docs/Web/HTML/Element'>HTML elements reference</BadgeLink>
## Style your pages with CSS
With the help of HTML, you create structure for your pages. CSS allows you to style your pages and make them pretty. If you take the analogy of human body, the skeleton would be the HTML, skin would be the CSS and muscles that help us move would be JavaScript - we will learn more about JavaScript in the coming sections.
* <BadgeLink badgeText='Read' href='https://www.w3schools.com/css/'>W3Schools CSS Tutorial</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=yfoY53QXEnI'>CSS Crash Course For Absolute Beginners</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=Wm6CUkswsNw'>Build An HTML5 Website With A Responsive Layout</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://youtu.be/JJSoEo8JSnc?t=46'>Flexbox CSS In 20 Minutes</BadgeLink>
## Basics of JavaScript
JavaScript allows you to add interactivity to your pages. Common examples that you may have seen on the websites are sliders, click interactions, popups and so on. In this section, you will learn the basics of JavaScript.
* <BadgeLink badgeText='Read' href='https://www.w3schools.com/js/'>W3Schools JavaScript Tutorial</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://youtu.be/hdI2bqOjy3c?t=2'>JavaScript Crash Course for Beginners</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://youtu.be/P7t13SGytRk?t=22'>Build a Netflix Landing Page Clone with HTML, CSS & JS</BadgeLink>
## Version Control Systems and Git
Version control systems allow you to track changes to your codebase/files over time. They allow you to go back to some previous version of the codebase without any issues. Also, they help in collaborating with people working on the same code if youve ever collaborated with other people on a project, you might already know the frustration of copying and merging the changes from someone else into your codebase; version control systems allow you to get rid of this issue.
In this section, you will learn what version control systems are and understand how to use Git which is the de facto VCS.
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=zbKdDsNNOhg'>Version Control System Introduction</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=SWYqp7iY_Tc'>Git & GitHub Crash Course For Beginners</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://youtu.be/Y9XZQO1n_7c?t=21'>Learn Git in 20 Minutes</BadgeLink>
Now that you know what git is go ahead and create an account on [GitHub](https://github.com) and push everything that you do from now on to GitHub so that you can get the practice and get it reviewed from the other people in the community.
## Modern JavaScript
In this section you will learn how to use package managers and get started with the "modern JavaScript".
* <BadgeLink badgeText='Read' href='https://medium.com/the-node-js-collection/modern-javascript-explained-for-dinosaurs-f695e9747b70'>Modern JavaScript for Dinosaurs (Don't worry if you don't understand some parts of it)</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=8Rmj5UY5mJk'>What is NPM and how to use it</BadgeLink>
* <BadgeLink badgeText='Watch' href='https://www.youtube.com/watch?v=jHDhaSSKmB0'>NPM Crash Course</BadgeLink>
<br />
<br />
<br />
<br />
<br />
<br />

View File

@@ -0,0 +1,41 @@
{
"seo": {
"title": "Learn to become a modern backend developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for modern backend development. Learn to become a modern backend developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a developer",
"guide to becoming a backend developer",
"backend developer",
"backend engineer",
"backend skills",
"backend development",
"javascript developer",
"backend development skills",
"backend development skills test",
"backend engineer roadmap",
"backend developer roadmap",
"become a backend developer",
"backend developer career path",
"javascript developer",
"modern javascript developer",
"node developer",
"skills for backend development",
"learn backend development",
"what is backend development",
"backend developer quiz",
"backend developer interview questions"
]
},
"title": "Backend Developer",
"description": "Step by step guide to becoming a modern backend developer in 2021",
"featuredTitle": "Backend",
"featuredDescription": "Step by step guide to becoming a backend developer in 2021",
"featured": true,
"imagePath": "/roadmaps/backend.png",
"resourcesPath": "./resources.md",
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"pdfUrl": "https://kamranahmedse.gumroad.com/l/backend-roadmap"
}

View File

@@ -0,0 +1,7 @@
> **We are still preparing the resources**. Please check back later or [subscribe to get notified](/signup).
While we prepare the list, follow this simple advice to learn anything
> Just **pick a project and start working on it**, you will learn all that you need along the way.
**&rarr;** &nbsp; [All Roadmaps](/roadmaps) &nbsp;&bull;&nbsp; [Programming guides](/guides) &nbsp;&bull;&nbsp; [Subscribe](/signup)

View File

@@ -0,0 +1,40 @@
{
"seo": {
"title": "DevOps Roadmap: Learn to become a DevOps Engineer or SRE",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for DevOps. Learn to become a modern DevOps engineer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a devops enginer",
"devops roadmap",
"sre roadmap",
"site reliability engineer roadmap",
"operations roles",
"become devops",
"devops skills",
"modern devops skills",
"devops skills test",
"skills for devops",
"learn devops",
"what is devops",
"what is sre",
"devops quiz",
"devops interview questions"
]
},
"title": "DevOps Roadmap",
"description": "Step by step guide for DevOps, SRE or any other Operations Role in 2021",
"featuredTitle": "DevOps",
"featuredDescription": "Step by step guide for DevOps or operations role in 2021",
"featured": true,
"imagePath": "/roadmaps/devops.png",
"resourcesPath": "./resources.md",
"versions": [
"latest",
"2018",
"2017"
],
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"pdfUrl": "https://kamranahmedse.gumroad.com/l/devops-roadmap"
}

View File

@@ -0,0 +1,7 @@
> **We are still preparing the resources**. Please check back later or [subscribe to get notified](/signup).
While we prepare the list, follow this simple advice to learn anything
> Just **pick a project and start working on it**, you will learn all that you need along the way.
**&rarr;** &nbsp; [All Roadmaps](/roadmaps) &nbsp;&bull;&nbsp; [Programming guides](/guides) &nbsp;&bull;&nbsp; [Subscribe](/signup)

View File

@@ -0,0 +1,7 @@
The intent of this guide is to give you an idea about the React ecosystem and to help guide your learning if you are confused. We have another [roadmap on the Frontend Development](/frontend) that focuses on the frontend development if you are interested in that.
Also, please note that the list below is exhaustive, and the items are listed in no particular order. You don't need to learn everything listed in the picture, however knowing what you don't know is as important as knowing things.
![](/roadmaps/react.png)
Please note that the list is opinionated, and you might have different opinions than those of the author. Having said that, [we would love to hear your opinions](https://github.com/kamranahmedse/roadmap.sh/issues/new) and incorporate them in the picture if suitable.

View File

@@ -0,0 +1,38 @@
{
"seo": {
"title": "React Developer Roadmap: Learn to become a React developer",
"description": "Community driven, articles, resources, guides, interview questions, quizzes for react development. Learn to become a modern React developer by following the steps, skills, resources and guides listed in this roadmap.",
"keywords": [
"guide to becoming a react developer",
"react developer roadmap",
"react roadmap",
"become react developer",
"react developer skills",
"react skills test",
"skills for react development",
"learn react development",
"what is react",
"react quiz",
"react interview questions"
]
},
"title": "React Developer",
"description": "Everything that is there to learn about React and the ecosystem in 2021.",
"featuredTitle": "React",
"featuredDescription": "Step by step guide to become a React Developer in 2021",
"isTextHeavy": false,
"isCommunity": false,
"featured": true,
"contentPath": "./landscape.md",
"resourcesPath": "./resources.md",
"versions": [
"latest",
"2018",
"2017"
],
"author": {
"name": "Kamran Ahmed",
"url": "https://twitter.com/kamranahmedse"
},
"pdfUrl": "https://kamranahmedse.gumroad.com/l/react-roadmap"
}

View File

@@ -0,0 +1,7 @@
> **We are still preparing the resources**. Please check back later or [subscribe to get notified](/signup).
While we prepare the list, follow this simple advice to learn anything
> Just **pick a project and start working on it**, you will learn all that you need along the way.
**&rarr;** &nbsp; [All Roadmaps](/roadmaps) &nbsp;&bull;&nbsp; [Programming guides](/guides) &nbsp;&bull;&nbsp; [Subscribe](/signup)

View File

@@ -1,45 +1,3 @@
---
pdfUrl: "/pdfs/roadmaps/postgresql-dba.pdf"
order: 5
featuredTitle: "DBA"
featuredDescription: "Step by step guide to become a PostgreSQL DBA in 2023"
title: "PostgreSQL DBA"
description: "Step by step guide to becoming a modern PostgreSQL DB Administrator in 2023"
hasTopics: false
seo:
title: "DBA Roadmap: Learn to become a database administrator with PostgreSQL"
description: "Community driven, articles, resources, guides, interview questions, quizzes for DevOps. Learn to become a modern DevOps engineer by following the steps, skills, resources and guides listed in this roadmap."
keywords:
- "guide to becoming a database administrator"
- "guide to becoming a DBA"
- "dba roadmap"
- "db administrator roadmap"
- "database administrator roadmap"
- "postgresql roadmap"
- "dba skills"
- "db administrator skills"
- "become dba"
- "postgresql skills"
- "modern dba skills"
- "dba skills test"
- "skills for dba"
- "skills for database administrator"
- "learn dba"
- "what is dba"
- "database administrator quiz"
- "dba interview questions"
relatedRoadmaps:
- "backend"
- "devops"
sitemap:
priority: 1
changefreq: "monthly"
tags:
- "roadmap"
- "main-sitemap"
- "role-roadmap"
---
The intent of this guide is to give you an idea about the DBA landscape and to help guide your learning if you are confused. The roadmap is highly opinionated — neither, knowing everything listed in the roadmap, nor the order of items given in the roadmap is required to be followed in order to be a DBA.
## Learn basic RDBMS terms and concepts
@@ -190,7 +148,7 @@ Get basic understanding about troubleshooting tools and get practical skills of
- [Linux Performance](http://www.brendangregg.com/linuxperf.html) by Brendan Gregg
- [USE Method](http://www.brendangregg.com/usemethod.html)
## Learn SQL optimization techniques
## Learn SQL optimization technics
Get understanding and practical skills of how to optimize SQL queries.
- **Indexes, and their use cases**: B-tree, Hash, GiST, SP-GiST, GIN, BRIN
- SQL queries patterns and anti-patterns
@@ -215,4 +173,8 @@ Get involved to Postgres community and contribute to Postgres; be a useful membe
- pgsql-hackers
- pgsql-bugs
- Reviewing patches
- Writing patches, attending in [Commitfests](https://commitfest.postgresql.org/)
- Writing patches, attending in [Commitfests](https://commitfest.postgresql.org/)
<br />
<br />
<br />

Some files were not shown because too many files have changed in this diff Show More