diff --git a/sidebar.json b/sidebar.json
index 7683e342..5e2775dd 100644
--- a/sidebar.json
+++ b/sidebar.json
@@ -477,6 +477,14 @@
"name": "3D Rendering with Three.js",
"slug": "38-3D-rendering-with-threejs"
},
+ {
+ "name": "Wordle with Python and Rich",
+ "slug": "39-two-player-wordle-clone-python-rich"
+ },
+ {
+ "name": "Multi-user static blog with Nix",
+ "slug": "40-build-host-company-blog-on-replit-with-hugo-nix"
+ },
{
"name": "Pinboard project part 1: HTML & CSS",
"slug": "pinboard-project-part-1"
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/clearedinputs.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/clearedinputs.png
new file mode 100644
index 00000000..c766fed9
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/clearedinputs.png differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/feedback.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/feedback.png
new file mode 100644
index 00000000..3681bf45
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/feedback.png differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/gameloop.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/gameloop.png
new file mode 100644
index 00000000..b85eee8e
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/gameloop.png differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/new-repl.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/new-repl.png
new file mode 100644
index 00000000..ab5719d1
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/new-repl.png differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/shell.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/shell.png
new file mode 100644
index 00000000..6c17529f
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/shell.png differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/twordledemo.mp4 b/static/images/tutorials/39-two-player-wordle-clone-python-rich/twordledemo.mp4
new file mode 100644
index 00000000..c5d9e2ac
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/twordledemo.mp4 differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/welcometowordle.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/welcometowordle.png
new file mode 100644
index 00000000..1002f34c
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/welcometowordle.png differ
diff --git a/static/images/tutorials/39-two-player-wordle-clone-python-rich/withemoji.png b/static/images/tutorials/39-two-player-wordle-clone-python-rich/withemoji.png
new file mode 100644
index 00000000..9a93a775
Binary files /dev/null and b/static/images/tutorials/39-two-player-wordle-clone-python-rich/withemoji.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/blogdemo.mp4 b/static/images/tutorials/40-multiuser-blog-nix/blogdemo.mp4
new file mode 100644
index 00000000..2566607b
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/blogdemo.mp4 differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/commitpush.png b/static/images/tutorials/40-multiuser-blog-nix/commitpush.png
new file mode 100644
index 00000000..60965439
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/commitpush.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/connect-github.png b/static/images/tutorials/40-multiuser-blog-nix/connect-github.png
new file mode 100644
index 00000000..9eb667c0
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/connect-github.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/create-repo.png b/static/images/tutorials/40-multiuser-blog-nix/create-repo.png
new file mode 100644
index 00000000..e3889337
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/create-repo.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/dev-repl.png b/static/images/tutorials/40-multiuser-blog-nix/dev-repl.png
new file mode 100644
index 00000000..57b91420
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/dev-repl.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/diagram.png b/static/images/tutorials/40-multiuser-blog-nix/diagram.png
new file mode 100644
index 00000000..2e78019e
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/diagram.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/empty-site.png b/static/images/tutorials/40-multiuser-blog-nix/empty-site.png
new file mode 100644
index 00000000..a4b95a05
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/empty-site.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/first-post.png b/static/images/tutorials/40-multiuser-blog-nix/first-post.png
new file mode 100644
index 00000000..1335e36d
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/first-post.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/fork-repl.png b/static/images/tutorials/40-multiuser-blog-nix/fork-repl.png
new file mode 100644
index 00000000..2fe9416b
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/fork-repl.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/github-repo.png b/static/images/tutorials/40-multiuser-blog-nix/github-repo.png
new file mode 100644
index 00000000..2afbf417
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/github-repo.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/hugo-files.png b/static/images/tutorials/40-multiuser-blog-nix/hugo-files.png
new file mode 100644
index 00000000..439f39f2
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/hugo-files.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/post-content.png b/static/images/tutorials/40-multiuser-blog-nix/post-content.png
new file mode 100644
index 00000000..76f7fbd3
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/post-content.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/pull.png b/static/images/tutorials/40-multiuser-blog-nix/pull.png
new file mode 100644
index 00000000..8fd89390
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/pull.png differ
diff --git a/static/images/tutorials/40-multiuser-blog-nix/thread.png b/static/images/tutorials/40-multiuser-blog-nix/thread.png
new file mode 100644
index 00000000..7dfe1942
Binary files /dev/null and b/static/images/tutorials/40-multiuser-blog-nix/thread.png differ
diff --git a/tutorials/39-two-player-wordle-clone-python-rich.md b/tutorials/39-two-player-wordle-clone-python-rich.md
new file mode 100644
index 00000000..c606cf9e
--- /dev/null
+++ b/tutorials/39-two-player-wordle-clone-python-rich.md
@@ -0,0 +1,326 @@
+# Building a two player *Wordle* clone with Python and Rich on Replit
+
+In this guide, we'll build a version of the popular game *Wordle*. Instead of the computer providing a word that the player has to guess, our version will work with two players. Player 1 will enter the word, and then player 2 will try to guess the word entered, similar to the popular game *Hangman*.
+
+Once you're done, you'll be able to play a command-line-based game with a friend (with both of you sitting at the same machine), as shown below.
+
+
+
+
+We'll be using Python, and to do the green and yellow colors we'll use [Rich](https://rich.readthedocs.io/en/stable/introduction.html), a library for rich-text formatting. To follow along, you should know some basic Python, but we'll explain each code sample in depth so you should be able to keep up even if you are not familiar with Python.
+
+## Getting started
+
+To get started, create a **Python** repl.
+
+
+
+
+## Installing Rich
+
+Rich isn't part of the Replit Universal Installer, so we have to install it manually. Open up the "Shell" tab in the repl workspace and run the following commands:
+
+```bash
+python3 -m poetry init --no-interaction
+python3 -m poetry add rich
+```
+
+This will create a `pyproject.toml` file to define Rich as a dependency, and Replit will automatically install it for us next time we run our app.
+
+
+
+## Printing colored text
+
+The first thing we need to figure out is how to print out different colored letters. By default, we'll use similar settings to the *Wordle* defaults
+
+* Green = correct letter in the correct position
+* Yellow = correct letter in the incorrect position
+* Gray = incorrect letter
+
+Because we're using Rich, we don't have to mess around with [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code). It's possible to use them to style terminal text, but you end up having to deal with nasty-looking strings like `\033[0;32m`, and there are likely to be compatibility issues too. Rich abstracts this away for us, and we can use nicer-looking controls like '[black on green]TWORDLE[/]' to describe how the text should look.
+
+Take a look at how this works now by adding the following code to `main.py` and pressing "Run":
+
+```python
+import rich
+
+rich.print('[black on green]TWORDLE[/]')
+```
+
+Because we may want to customize what specific colors mean at some point, let's define each of our three cases in functions. Replace the existing code in `main.py` with the following:
+
+```python
+import rich
+
+def correct_place(letter):
+ return f'[black on green]{letter}[/]'
+
+def correct_letter(letter):
+ return f'[black on yellow]{letter}[/]'
+
+def incorrect(letter):
+ return f'[black on white]{letter}[/]'
+
+WELCOME_MESSAGE = correct_place("WELCOME") + " " + incorrect("TO") + " " + correct_letter("TWORDLE") + "\n"
+
+def main():
+ rich.print(WELCOME_MESSAGE)
+
+if __name__ == '__main__':
+ main()
+```
+
+Run this code, and you'll see a Wordle-styled welcome message, demonstrating all three styles, as shown below.
+
+
+
+
+## Creating the game loop
+
+As in classic *Wordle*, our game will allow the player six tries to guess a word. Unlike classic *Wordle*, we'll allow for two players. Player 1 will choose a word, and player 2 will attempt to guess it. The basic logic is then:
+
+```
+Get word from Player 1
+Get guess from Player 2
+While Player 2 has guesses remaining
+ Get new guess
+ If guess is correct
+ End the game
+```
+
+So let's ignore our fancy colored text for a moment and build this logic.
+
+### Getting and guessing the word
+
+We'll use the `Console` class from Rich, which creates a virtual output pane on top of our actual console. This will make it easier to have more control over our output as we build out the app.
+
+Add the following two imports to the top of the `main.py` file:
+
+```python
+from rich.prompt import Prompt
+from rich.console import Console
+```
+
+And now replace the `main()` function with the following code:
+
+```python
+def main():
+ rich.print(WELCOME_MESSAGE)
+
+ allowed_guesses = 6
+ used_guesses = 0
+
+ console = Console()
+ answer_word = Prompt.ask("Enter a word")
+ console.clear()
+
+ while used_guesses < allowed_guesses:
+ used_guesses += 1
+ guess = Prompt.ask("Enter your guess")
+ if guess == answer_word:
+ break
+ print(f"\n\nTWORDLE {used_guesses}/{allowed_guesses}\n")
+```
+
+If you run this, you'll be prompted (as player 1) to enter a word. The entered word will then be hidden from view to avoid spoiling the game, and player 2 can enter up to six guesses. At this stage, player 2 doesn't get any feedback on correct or incorrect letters, which makes the game pretty hard for player 2! If player 2 does happen to guess correctly, the loop will break and the game will display how many guesses were used.
+
+
+
+
+
+### Providing feedback on correct letters
+
+Let's add a helper function to calculate whether each letter should be green, yellow, or gray. Add this function above the `main()` function in `main.py`:
+
+```python
+def score_guess(guess, answer):
+ scored = []
+ for i, letter in enumerate(guess):
+ if answer[i] == guess[i]:
+ scored += correct_place(letter)
+ elif letter in answer:
+ scored += correct_letter(letter)
+ else:
+ scored += incorrect(letter)
+ return ''.join(scored)
+```
+
+This function takes in player 2's guess and the correct answer and compares them letter by letter. It uses the helper functions we defined earlier to create the Rich formatting string for each letter, and then joins them all together into a single string.
+
+
+
+
+## Adding an emoji representation for spoiler-free sharing
+
+A key part of *Wordle* is that once a player has guessed a word, they can share a simple graphic of how well they did, without giving away the actual word. For our two-player version, this "no spoilers" feature isn't as important, but let's add it anyway.
+
+As with the letter-coloring, we want to keep the emoji we use configurable. By default, we'll use green, yellow, and gray squares. Let's start by defining this in a dictionary, near the top of our `main.py` file. Add the following to your code:
+
+```python
+emojis = {
+ 'correct_place': '🟩',
+ 'correct_letter': '🟨',
+ 'incorrect': '⬜'
+}
+```
+
+Replace the `score_guess` function with the following:
+
+```python
+def score_guess(guess, answer):
+ scored = []
+ emojied = []
+ for i, letter in enumerate(guess):
+ if answer[i] == guess[i]:
+ scored += correct_place(letter)
+ emojied.append(emojis['correct_place'])
+ elif letter in answer:
+ scored += correct_letter(letter)
+ emojied.append(emojis['correct_letter'])
+ else:
+ scored += incorrect(letter)
+ emojied.append(emojis['incorrect'])
+ return ''.join(scored), ''.join(emojied)
+```
+
+The logic is very similar to before, but instead of only calculating the correct style for the letter, we also keep track of each emoji. At the end, we return both the string to print out the scored word, and the emoji representation for that guess.
+
+To use this in the main function, replace the code for the `while` loop with the following code:
+
+```python
+ all_emojied = []
+ while used_guesses < allowed_guesses:
+ used_guesses += 1
+ guess = Prompt.ask("Enter your guess")
+ scored, emojied = score_guess(guess, answer_word)
+ all_emojied.append(emojied)
+ console.print(scored)
+ if guess == answer_word:
+ break
+ print(f"\n\nTWORDLE {used_guesses}/{allowed_guesses}\n")
+ for em in all_emojied:
+ console.print(em)
+```
+
+If you run again, the game will work as before, but now you'll see the emoji representation printed after the game ends. This can be copy-pasted to share and help our game go viral. You can see what it looks like in the image below.
+
+
+
+## Some finishing touches
+
+The one messy part of our game remaining is that the input prompts are still shown after player 2 has entered each guess. This means that each word is shown twice: once in its colored form, and once exactly as the player entered it. Let's adapt the game to clear the console and output just the colored versions of each guess.
+
+To do this, we need to keep track of all player 2's guess, which we were not doing before.
+
+Replace the `while` loop in the `main()` function with the following code:
+
+```python
+ all_emojied = []
+ all_scored = []
+ while used_guesses < allowed_guesses:
+ used_guesses += 1
+ guess = Prompt.ask("Enter your guess")
+ scored, emojied = score_guess(guess, answer_word)
+ all_scored.append(scored)
+ all_emojied.append(emojied)
+ console.clear()
+ for scored in all_scored:
+ console.print(scored)
+ if guess == answer_word:
+ break
+```
+
+This clears the console completely after each guess by player 2, and then prints out each of the (styled) guesses. The output looks neater now, as shown below.
+
+
+
+### Adding instructions
+
+People will like our game more if they can figure out what to do without having to read documentation. Let's add some basic instructions for each player to the game interface. Below the `WELCOME_MESSAGE` variable we defined earlier, add the following:
+
+```python
+P1_INSTRUCTIONS = "Player 1: Please enter a word (player 2, look away)\n"
+P2_INSTRUCTIONS = "Player 2: You may start guessing\n"
+```
+
+Now update the `main()` function like this:
+
+```python
+def main():
+ allowed_guesses = 6
+ used_guesses = 0
+
+ console = Console()
+ console.print(WELCOME_MESSAGE)
+ console.print(P1_INSTRUCTIONS)
+ answer_word = Prompt.ask("Enter a word")
+ console.clear()
+ console.print(WELCOME_MESSAGE)
+ console.print(P2_INSTRUCTIONS)
+
+ all_emojied = []
+ all_scored = []
+ while used_guesses < allowed_guesses:
+ used_guesses += 1
+ guess = Prompt.ask("Enter your guess")
+ scored, emojied = score_guess(guess, answer_word)
+ all_scored.append(scored)
+ all_emojied.append(emojied)
+ console.clear()
+ console.print(WELCOME_MESSAGE)
+ for scored in all_scored:
+ console.print(scored)
+ if guess == answer_word:
+ break
+ print(f"\n\nTWORDLE {used_guesses}/{allowed_guesses}\n")
+ for em in all_emojied:
+ console.print(em)
+```
+Now our welcome message stays at the top, and the players are prompted by simple instructions. Have fun playing it with your friends!
+
+## Where next?
+
+The basics of the game are in place, but there is still a lot you could build from here. Some ideas:
+
+* Fix the logic for handling duplicate letters.
+* Fix the fact that the game crashes if player 2 enters the wrong number of letters.
+* The game still says `6/6`, even if player 2 has not guessed the word after six tries. Have the game print out `X/6` in this case, as in classic *Wordle*.
+* Give player 2 more guesses based on the length of the word player 1 enters.
+* [CHALLENGING] Make the game work over the internet instead of requiring both players to be in same room.
+
+
+You can find the code for this tutorial here:
+
+
diff --git a/tutorials/40-build-host-company-blog-on-replit-with-hugo-nix.md b/tutorials/40-build-host-company-blog-on-replit-with-hugo-nix.md
new file mode 100644
index 00000000..a2b85bb4
--- /dev/null
+++ b/tutorials/40-build-host-company-blog-on-replit-with-hugo-nix.md
@@ -0,0 +1,295 @@
+# Build and host your company blog on Replit with Nix and Hugo
+
+In this tutorial, we will detail how you can use Replit to write and publish a blog or website. This can be a solo endeavour or a group or company blog. We'll build on the versatile Nix repl, using a static site generator called [Hugo](https://gohugo.io/) to ensure our site is fast, secure and flexible. We'll also use some repl tricks which will allow us to develop and host our blog without ever leaving Replit.
+
+
+
+After this tutorial, you will:
+
+* Be familiar with setting up a static website using Hugo.
+* Understand how to connect multiple repls through GitHub.
+* Find new uses for Replit's collaborative features.
+
+## Repl architecture
+
+This project will make use of two repls:
+
+* A **development repl**, which will be used to write and preview draft posts and make site changes. This repl will be where all development happens.
+* A **production repl**, which will be used to host a public version of the site. This repl will be updated from GitHub when new posts are made public.
+
+If you have a premium Replit plan, you might want to make these repls private, to prevent people from finding your unfinished posts.
+
+## Creating the working repl
+
+Log into your [Replit account](https://replit.com/login) and create a new repl. Choose Nix as your project type. Give this repl a name, like "blog-dev".
+
+
+
+Most kinds of repls are intended for working in a specific programming language or framework, such as Python or Kaboom.js. Nix repls are different: you can think of them as a blank slate for running anything you want. So the first thing we need to do in our repl is define what we're going to run – in this case it will be Hugo. Open `replit.nix` and append `pkgs.hugo` to the `deps` list. Your file should look like this:
+
+```nix
+{ pkgs }: {
+ deps = [
+ pkgs.cowsay
+ pkgs.hugo
+ ];
+}
+```
+
+This will install Hugo the next time we run our repl. If you'd like to understand more about what this code is actually doing, check out the tutorial on [building with Nix on Replit](https://docs.replit.com/tutorials/30-build-with-nix).
+
+Run your repl now. Once you see the ASCII cow in the repl console, type the following command:
+
+```sh
+hugo new site --force .
+```
+
+This will create a new Hugo site in our repl. The `--force` flag is necessary because Hugo usually doesn't like creating new sites in directories that already contain files.
+
+You should now see a number of new directories and files in your repl's file pane. This is the skeleton of your Hugo site. Don't worry about what each of these files and directories is for – you only need to know about a few of them to start blogging, and we'll explain them as we go.
+
+
+
+Because Hugo is highly flexible and unopinionated, it doesn't even come with a default theme, so we won't be able to see our site in action until we choose one. There are a large number of choices on [Hugo's official themes website](https://themes.gohugo.io/). For this tutorial, we'll be using [Radek Kozieł](https://radoslawkoziel.pl/)'s [Terminal](https://themes.gohugo.io/themes/hugo-theme-terminal/) theme, but feel free to pick a different one later.
+
+To install the theme, run the following command in your repl's console:
+
+```sh
+cd themes && git clone https://github.com/panr/hugo-theme-terminal && cd ..
+```
+
+This will use Git to download the theme into our site's `themes` directory. To instruct our site to use this theme, add the following line to the bottom of `config.toml`:
+
+```toml
+theme = 'hugo-theme-terminal'
+```
+
+We must now configure our repl to host our static site so that we can see the results of our work. If you're familiar with static site generators (perhaps from a [previous tutorial](https://docs.replit.com/tutorials/16-static-site-generator)), you'll know that this is a two-step process:
+
+1. Render content in markdown and insert it into theme templates to create HTML pages.
+2. Host those HTML pages on a web server.
+
+Hugo includes a built-in command that does both, [`hugo server`](https://gohugo.io/commands/hugo_server/). We can make this the command that executes when we click our repl's run button by editing the `run` directive in the `.replit` file as below:
+
+```sh
+run = "hugo server --buildDrafts --buildFuture --bind 0.0.0.0 --port 443 --baseURL https://YOUR-REPL-NAME-HERE.YOUR-USERNAME-HERE.repl.co"
+```
+
+In this command:
+
+* `--buildDrafts` and `--buildFuture` will ensure that all site content is rendered, even if it's marked as a draft or scheduled for publishing in the future.
+* `--bind` `--port` and `--baseURL` are all used to [ensure that our repl will host our site correctly](https://docs.replit.com/hosting/deploying-http-servers). Make sure to modify the argument for `--baseURL` as indicated (i.e. replacing the placeholders `YOUR-REPL-NAME-HERE` and `YOUR-USERNAME-HERE` with your own values).
+
+Run your repl. You should see an empty site homepage.
+
+
+
+To create your first post, run the command below in the repl shell. Press Y when prompted to run Hugo from Nix:
+
+```sh
+hugo new posts/first-post.md
+```
+
+Your site will automatically reload and should now look like this:
+
+
+
+You should see a file named `first-post.md` in the `content/posts` directory with contents resembling the following:
+
+```markdown
++++
+title = "First Post"
+date = "2022-01-30T11:21:41Z"
+author = "Your name"
+authorTwitter = "Your Twitter"
+cover = ""
+tags = ["", ""]
+keywords = ["", ""]
+description = ""
+showFullContent = false
+readingTime = false
++++
+```
+
+The text between the `+++` lines is called [front matter](https://gohugo.io/content-management/front-matter/) and defines metadata for your post, such as its title, author and time posted. Post content can be added as markdown-formatted text below the final `+++`. Add some now.
+
+```markdown
++++
+title = "First Post"
+date = "2022-01-30T11:21:41Z"
+author = "Your name"
+authorTwitter = "Your Twitter"
+cover = ""
+tags = ["", ""]
+keywords = ["", ""]
+description = ""
+showFullContent = false
+readingTime = false
++++
+
+## Hello world!
+
+This *is* **my** `first` post!
+```
+
+
+
+## Preparing for production
+
+We now have a functional workspace in which to develop our site, but we need to make a few alterations before it's ready for public consumption. First, let's make it easier to keep unfinished posts as drafts. By default, posts created using the Terminal theme will appear as published as soon as they're created – this is probably not what we want. Luckily, it's an easy fix.
+
+Hugo stores content templates in a directory called [archetypes](https://gohugo.io/content-management/archetypes/). You should see an empty directory with this name in your repl's file pane. Archetype files are named after the content type (e.g. post or page) they're used for – currently, our `archetypes` directory only has a single file, named `default.md`, which will be used for content types without custom archetypes. However, if you look at the contents of `default.md`, you'll notice that it looks nothing like the post we created above. This is because Hugo doesn't just look for archetypes in our site skeleton, but also in our chosen theme.
+
+You should find a file named `posts.md` in `themes/hugo-terminal-theme/archetypes/`. The contents of this file will resemble the new post you made in the last section. Duplicate this file, move it into your top-level `archetypes` directory, and rename it to `posts.md`. Then, in the new file, add the line `draft = true` just above the final `+++`. Your `archetypes/posts.md` file should look like this:
+
+```md
++++
+title = "{{ replace .TranslationBaseName "-" " " | title }}"
+date = "{{ .Date }}"
+author = ""
+authorTwitter = "" #do not include @
+cover = ""
+tags = ["", ""]
+keywords = ["", ""]
+description = ""
+showFullContent = false
+readingTime = false
+draft = true
++++
+```
+
+If a file in a top-level directory has the same name as a file in the equivalent theme directory, the former will override the latter. This allows us to make site-specific tweaks without changing our theme. Create a new post by entering the following command into your repl's shell:
+
+```sh
+hugo new posts/second-post.md
+```
+
+This post and all subsequent new posts will be marked as drafts, and will thus only be included in our website if we run Hugo with the `--buildDrafts` flag. This will be useful for when we create our production repl. But before we can do that, we need to prepare this development repl to connect to it by creating a GitHub repository.
+
+Select the version control tab in your repl's side pane and click on **Create a Git Repo**. This will create a local repository to track your code changes. From here, you can create snapshots of your code (called commits), which can you can revert to if needed.
+
+
+
+To push our repl to a repository on GitHub, we'll need a GitHub account. [Create one](https://github.com/signup) if you haven't before. Once you've created an account or logged into your existing one, return to your repl and click on **Connect to GitHub**. Accept the Oauth confirmation message that appears.
+
+
+
+Replit will then prompt you to specify a repository name, optional description and privacy setting. You can call your repository "blog". If you have a paid Replit plan, you can make it private, otherwise it will have to be public. Once you've created the GitHub repository, you'll be able to view it on your GitHub account.
+
+
+
+Now that your repl is connected to a GitHub repository, any time you make changes, those will be reflected in the version control tab. To commit those changes and push them to your GitHub repository, you can click on **Commit and push** in your repl's version control tab. You will be required to specify a commit message describing the changes you've made.
+
+If our production repl will be sharing a code repository with our development repl, how will we ensure that drafts and future content aren't shown in production? One solution might be to use different branches, but that would require constant merging. All that really needs to change between development and production is the command that gets executed when we click the Run button. We'll use a bit of repl magic to make this work.
+
+First, replace the `run` directive in the `.replit` config file with the following:
+
+```sh
+run = "sh run.sh"
+```
+
+Then create a file named `run.sh` and add the following code to it:
+
+```sh
+#!/bin/bash
+
+if [ "$REPL_SLUG" == 'blog-dev' ] # draft space
+then
+ hugo serve --buildDrafts --buildFuture --bind 0.0.0.0 --port 443 --baseURL https://$REPL_SLUG.$REPL_OWNER.repl.co
+else # production
+ hugo serve --bind 0.0.0.0 --port 443 --baseURL https://$REPL_SLUG.$REPL_OWNER.repl.co
+fi
+```
+
+Here we've used a couple of [repl metadata environment variables](https://docs.replit.com/programming-ide/getting-repl-metadata) to trigger different behavior when our code is run in different repls.
+
+Return to your repl's version control tab and commit and push your changes. We are now ready to create the production repl.
+
+
+
+## Creating the production repl
+
+Fork your development repl. Give the new repl a different name, such as "blog".
+
+
+
+Since we've forked our development repl, both repls will be backed by the same repository on GitHub. This means we can commit and push changes from one repl (development) and pull those changes into the other repl (production). We could also achieve this by creating a new repl from our GitHub repository, but forking is quicker.
+
+When your production repl is run, you should see an almost identical website to the one in your development repl. The only difference should be that the second post won't appear in the production repl, as it is a draft.
+
+Let's test out our publishing flow.
+
+1. In your **development** repl, add some text to `content/posts/second-post.md`. Specify some or all of the front matter, such as your author name and Twitter account.
+2. Set `draft = false` in the post's front matter.
+3. From the **development** repl's version control tab, commit and push your changes.
+4. In your **production** repl, navigate to the version control tab and click on the "← Pull" link. This will pull the changes we just pushed from development.
+
+
+
+5. Rerun your **production** repl. You should now see the contents of the second blog post live on the website.
+
+This will be your workflow for publishing posts. Undraft, commit and push on development, then pull and rerun on production.
+
+If you have a paid Replit plan, you should set your production repl as [Always-on](https://docs.replit.com/hosting/enabling-always-on), so that people will always be able to reach your website.
+
+You will probably also want to use a custom domain name, instead of `blog.your-name.repl.co`. Instructions for setting this up are provided [here](https://docs.replit.com/hosting/hosting-web-pages#custom-domains). As a bonus, following this process will also put your site behind [Cloudflare](https://www.cloudflare.com/)'s content delivery network (CDN), improving its performance and reachability across the global internet. Cloudflare is [free for personal and hobby projects](https://www.cloudflare.com/plans/#overview).
+
+## Writing posts
+
+Now that we have a publishing platform in place, let's take a more detailed look at how to create content in Hugo.
+
+The basis of all Hugo blogs is [Markdown](https://daringfireball.net/projects/markdown/), a simple mark-up language for the web, originally created in 2004 by John Gruber. Markdown provides a simple, limited syntax, focused on the common needs of bloggers and other web-based writers. Basic Markdown elements are limited to headings, **bold**, *italic* and `code-style` text, blockquotes, lists, code blocks, horizontal rules, links and images. Markdown has been extended over the years to provide more advanced formatting, such as tables and footnotes. A cheat sheet covering both basic and extended syntax can be found [here](https://www.markdownguide.org/cheat-sheet/) (Hugo supports both basic and extended Markdown).
+
+To include images in your posts, upload them to the `static` directory. All files and subdirectories in `static` will be rendered as-is from your website's root URL. For example, if you create a file named `static/images/pic.png`, you will be able to include it in your posts by writing ``. You can put anything you want in `static`, including documents, audio files, or even videos.
+
+If you want formatting that isn't included in Markdown, such as colored text, you can add HTML and CSS to your posts directly, but first you must configure Hugo's Markdown parser (Goldmark) to accept unsafe input. Add the following lines to `config.toml`:
+
+```toml
+[markup.goldmark.renderer]
+unsafe = true
+```
+
+Stop and start your repl for the config change to take effect.
+
+Hugo also provides functionality called [shortcodes](https://gohugo.io/content-management/shortcodes/), which you can think of as HTML [macros](https://en.wikipedia.org/wiki/Macro_(computer_science)). Hugo provides built-in shortcodes for common tasks such as embedding [tweets](https://gohugo.io/content-management/shortcodes/#tweet) and [YouTube videos](https://gohugo.io/content-management/shortcodes/#youtube). You can also [create your own custom shortcodes](https://gohugo.io/templates/shortcode-templates/).
+
+Replit's multiplayer editing features aren't only good for collaborative programming, but can also be used for collaborative blogging. Multiple users can work in the same file in real time, and you can use [inline code threads](https://blog.replit.com/threads) to leave each other feedback and discuss individual words and sentences.
+
+
+
+If you need to include diagrams in your blog posts, you can draw them using your repl's [built-in Excalidraw](https://blog.replit.com/draw). Just create a new file with a `.draw` extension and start diagramming. When you're done, select your diagram, right-click and chose "Copy to clipboard as SVG". Then paste into the post you want to include the diagram in. Note that Goldmark must be configured in the manner shown above for this to work, as SVG images are part of HTML.
+
+
+
+## Where next?
+
+You've now got a fully functional static blog hosted on Replit. Some things you might want to do with it:
+
+* Learn more about Hugo from [the official documentation](https://gohugo.io/documentation/).
+* Choose a different theme from the [Hugo themes showcase](https://themes.gohugo.io/) or [create your own](https://gohugo.io/commands/hugo_new_theme/).
+* Get a few collaborators and write some more blog posts.
+
+You can find our development and production repls below:
+
+**Development**
+
+
+
+**Production**
+
+
+