- This is a free, open-source course platform for the #100devs program that teaches you what you need to get a job as a web developer.
- This course has an interactive code playground that allows you to directly preview code.
- 🌟 Add and display users' completion data.
- 🔥 Fix vulnerabilities on the server and microservice-side.
- 🧠 Include Anki-like flashcard features right on the platform.
- 🎬 Add video recordings to the platform to make the content more engaging.
- 📺 Synchronize live-streaming from the @learnwithleon channel on Twitch.
- 🪄 More lessons and modules!
- 🧑💻 Ensure support for React and add Jest compatibility to the code playground and improve its stability.
- 💻 Add support for directory and non-textual assets to the playground using Amazon S3 along with monkey-patching as much of Sandpack as necessary.
-
All lessons' textual content is stored in the
/src/content
directory. -
The
/src/content
directory is organized into folders that always contain amodule.json
file. -
Each folder must start with a numeric string with 2 digits, and tokens must be joined with hyphens. For example:
01-introduction // Valid 01_introduction // Invalid full_stack_with_express // Invalid 05-full-stack-with-express // Valid
-
The numeric strings must increment continously, starting from 1, 2, 3,...
-
The value inside
/src/content/${MODULE_NAME}/module.json
must be an object with 2 properties:title
: The name of the module that is displayed to the user.description
: Brief description of what the content displays.
-
Similar to folder names of modules, lesson names must also start with a 2-digit numeric strings that increment from 1 (which is how lessons are ordered) and tokens must be joined with hyphens.
-
All lesson files are MDX files and therefore should have a
.mdx
extension. -
The beginning of every MDX file must be a YAML header with 3 keys:
title
: The name of the lesson that is displayed to the user.publishedOn
: The date-time string. Should be a ISO-formatted time string that can be parsed._id
: The ID of the lesson, generated using thenpm run generate-id
helper script that gets a standard MongoDB ID object. This value must never be changed throughout the lifetime of the app.
- You should always use a HTML tag without issue, similar to traditional markdown.
- To check which components you're allowed to use, look for the
CustomMDXRemote
component, which has a key-to-component mapping. - For example, there is a
PathSimulator
key in the component map. That means you can use a<PathSimulator/>
element in any MDX file. - To enhance a lesson's interactivity and make it more engaging, you can create a custom component in the
/src/components
directory, then add a directory in theCOMPONENT_MAP
object.
-
Lesson images should always be served through the
<ServerImage/>
component, which makes a few optimizations ahead of time, instead of through the traditionalimg
tag. -
To add an image, go to the asset server repository. All assets necessary for your lesson should be stored in this path format
/static/${MODULE_NUMBER}/${LESSON_NUMBER}/${ASSET_NAME}.jpg
. For example, if you're in module 3 and lesson 5, you should use this path:/static/03/05/asset.png
-
After that, you can include your image in MDX by passing correct
slug
andalt
properties:<ServerImage slug="/03/05/asset.png" alt="This is an example asset"/>
-
Interactive code playgrounds should always be served through the
<CodePlayground/>
component. -
Playgrounds are stored in this repository.
-
Each code playground's base folder path should follow the same rules as in images. For example, a code playground named
test-playground
used in lesson 4 and module 7's root folder should have a path like this:/repositories/04/07/test-playground
-
Each playground MUST have a
package.json
file generated by npm init plus extra Sandpack-specific configurations stored in thesandpack
property. Here is an example file - notice the custom sandpack key:{ "name": "non-root-relative-url-quirks", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "sandpack": { "initialActiveFile": "/index.html", "files": { "/package.json": { "hidden": true }, "/package-lock.json": { "hidden": true } }, "startRoute": "/index.html", "environment": "static" } }
-
The Sandpack object in package.json has these keys:
initialActiveFile
: The path to the file which the code editor starts on. In most cases, it is also the file which you want students to focus on most.files
: An object storing the file's Sandpack configuration. It is a key-value store where:- The keys represent the path to a file. Don't end the path with a slash, or bugs will occur.
- The values are objects with these properties:
hidden
: Set it to true if you want to hide it in the code editor.readOnly
: Disallow the user to write to the file.
startRoute
: The starting URL of the preview window/frame.environment
: The environment which the code will be executed. Can besandpack
orcreate-react-app
. Other values should be supported (check Sandpack documentation) but it might not work due to the playground being completely custom.externalResources
: Any CSS or JavaScript files that you want to additionally load. For example, you can specify areset.css
file.
- Lesson contributions on this repository must link to another pull request on the asset server repository if you add any assets to your lesson and another on the code playgrounds repository if you add any code playgrounds.
- Any pull requests in the supporting microservice repositories that are not linked to a PR in this repository will be withheld or rejected.
- You can DM me on Twatter or join the 100Devs Discord server. The 100Devs fellows are happy to help!
This course platform is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
In other words - sharing or creating a better copy of the course platform is encouraged! However, the copy must also be free of charge for its users.