Chapters
- 0:00 Introduction
- 0:13 Create the project
- 0:52 Start the site
- 1:08 Run the setup wizard
- 1:35 A tour of the admin
- 3:00 Settings
- 3:21 Posts and the editor
- 4:10 Media
- 4:24 Menus
- 4:37 Redirects
- 4:51 Plugins: Comment Spam Protection
- 5:49 The finished site
By the end of this walkthrough, you will have an EmDash blog with a published post, a menu link, a redirect and a comment spam filter, and you will know your way around the admin. This walkthrough was tested on EmDash 1.1.0 on October 2, 2026, using Astro 7.3.5 and the Node.js Blog template.
What you need
You need Node.js, a terminal where you can type commands, and a browser that supports passkeys. You can work locally without a cloud account.
Install the current Node.js 24 release (24.15 or later). The video was recorded on Node 25, where npm install printed an EBADENGINE warning because one EmDash package asks for ^22.22.2 || ^24.15.0 || >=26.0.0. The site still built and ran in that test.
Create the project
Open your terminal and run:
npm create emdash@latest
The project is the folder that holds your site’s files. Follow the installer prompts:
- Enter a project name, such as
my-site. - Choose Node.js for the walkthrough. This uses a SQLite file for content and a local folder for uploads. Cloudflare Workers uses D1 for the database and R2 for storage. Your choice sets the adapters in
astro.config.mjs. - Choose Blog, the template shown in the video. It includes a design and sample posts. The other choices are Starter, Marketing and Portfolio.
- Choose your package manager and let the installer install dependencies.
The installer writes EMDASH_ENCRYPTION_KEY to .env and adds .env to .gitignore. EmDash uses this key to encrypt plugin secrets. Keep the file private and back up the key separately, because a database backup does not contain it. If you need to generate a new key, the command is:
npx emdash secrets generate
When the installer says Done, you can start the site.
Run it and sign in
Move into your project folder and start the development server. Replace my-site with the name you chose:
cd my-site
npm run dev
Open http://localhost:4321, then follow the admin link, or open http://localhost:4321/_emdash/admin directly.
- Enter your site title and tagline in the setup wizard.
- Keep the sample content, or choose an empty site.
- Enter your email and name.
- Create a passkey and sign in.
A passkey is a login saved on your device that you use with your fingerprint or device password. It belongs to the address where you created it. Your passkey for localhost will not work on your live domain, so you will need a new one there.
The terminal also prints a Dev bypass link (/_emdash/api/setup/dev-bypass?redirect=/_emdash/admin). It signs you in as a dev admin without a passkey and returns 403 outside development. The video follows the setup wizard.
A tour of the admin
- Dashboard shows a summary of your content and your latest changes.
- Calendar shows your published and scheduled posts by month.
- Pages holds pages that rarely change, such as an About page.
- Posts holds your blog posts, with their status and date.
- Media is your library of uploaded images and files.
- Comments lets you approve, reject or delete visitors’ comments.
- Menus controls rows of links, such as the navigation at the top of your site.
- Redirects sends visitors from an old address to a new one and lists pages that were not found.
- Widgets provides small blocks for areas such as the sidebar and footer, including a search box.
- Sections holds reusable content, such as an author bio, for posts and pages.
- Categories groups your posts into broad topics.
- Tags adds smaller labels, and a post can have as many as you like.
- Bylines holds the names shown as post authors, including guest writers.
- Content Types defines the kinds of content on your site and their fields.
- Byline Schema adds fields to bylines, such as a job title.
- Users lets you invite people and choose what they are allowed to do.
- Plugins lists installed add-ons that add features to your site.
- Registry is the public catalog where you find new plugins.
- Import brings in posts and pages from a WordPress site.
- Settings holds your site’s name, logo, search engine options and security.
Settings
In the tested EmDash 1.1.0 install, the title and tagline entered in the wizard did not replace the template’s values. The template’s seed is applied on the first request before the wizard runs, and the wizard does not overwrite it. The site still said My Blog.
- Open Settings → General.
- Enter your site title and tagline again. The video uses Long Walks as the title.
- Save your changes.
This page also holds your logo, favicon and Site URL. The favicon is the small icon in the browser tab. The Site URL is used for canonical links and sitemaps.
Write and publish a post
- Open Posts and select Add New. You can filter existing posts by status, author and date.
- Type a title and your first paragraph. Type
/to open the block menu, which includes headings, lists, quotes, code, tables, images and galleries. The toolbar has bold, italics, links, lists and quotes. - Under Featured Image, select browse, then Upload files. Upload a photo from your computer and choose it as the post’s main picture.
- Check the slug on the right. This is the end of the post’s web address, and EmDash fills it in from your title.
- Select Save. The panel reads “Draft version: This version is not visible on the site”.
- Select Publish now and confirm.
- Open the post on your site to check its title, image and text. Next, add alt text to the image in Media, as shown below.
After a post is live, new edits are saved as draft changes. Visitors keep seeing the published version until you select Publish changes. You can also Discard changes. Restoring an earlier version from Revisions gives you a draft to review and publish.
Schedule publishes later. On Node.js, the scheduler runs inside the server process, so your server has to be running at the scheduled time.
Media
Your featured image now appears in Media, along with your other uploads.
- Select the photo to open its details.
- Add alt text: a short description of the picture for people who use screen readers.
- Save it.
On the Node.js template, uploaded files are in ./uploads and content is in the SQLite file ./data.db, both in your project folder. On Cloudflare, uploads live in R2 and content lives in D1.
Menus
- Open Menus → Primary Navigation.
- Select Add Custom Link.
- Enter a label and the address of the post you published.
- Load the site again to check the new link in the header.
The Blog template’s header reads this menu, so your link appears on the next page load. You can also use Add Content to add content to the menu.
Redirects
A redirect is useful when you rename a page or want a short link. The video creates /trail as a shortcut to the published post.
- Open Redirects and select New Redirect.
- Enter
/trailas the old address. - Enter your published post’s address as the new address and create the redirect.
- Visit
http://localhost:4321/trailto check that you land on the post.
Plugins: install Comment Spam Protection
Comment Spam Protection checks new comments against your rules and explains why each comment was approved, held for review or marked as spam. The checks run on your own site without an outside service, account or API key. The blocked phrase rule used here is available in the free version.
One-time setup: turn on the plugin sandbox
Plugins from the EmDash registry run in a sandbox, which limits what they can access. You turn on the site’s sandbox runner once during site setup. The step depends on where the site runs. In the video we do this on a local test site because it runs on Node.js. A live site on a Node.js server needs the same one-time setup. After the runner is on, installing any registry plugin is just Install in the admin; you do not repeat the configuration for each plugin.
For Node.js, on your computer or a server:
- Stop the running site with Control+C and install both packages:
sh
npm install @emdash-cms/sandbox-workerd workerd
- In
astro.config.mjs, add this one line inside the existingemdash({ ... })options and save:
js
sandboxRunner: "@emdash-cms/sandbox-workerd/sandbox",
- Restart the local development site:
sh
npm run dev
For Cloudflare, there is no package to install. In wrangler.jsonc, uncomment the template’s "worker_loaders": [{ "binding": "LOADER" }] binding. This requires the Workers Paid plan. The template leaves it commented out so the site can deploy on the free plan. See the plugin sandbox guide.
Install and test the plugin
- Open Registry in the admin, search for Comment Spam Protection, and open it.
- Review the permissions EmDash shows, including comment moderation, then select Accept and Install.
- Open the plugin’s Comment rules page and select the Content tab.
- Add
crypto giveawayas a blocked word or phrase. Leave Mark as spam selected and save. - Open Try a comment and test a sample comment containing
crypto giveaway. This checks your rules without posting a comment. - Check the result. The video shows the test marked as spam, with the reason for the decision.
If comments are not enabled, open the collection under Content Types and turn on Enable comments so visitors can leave them.
Put the site online
You need a host that keeps your site running for visitors. The video finishes with the Node.js commands and Cloudflare setup notes.
Node.js production
Before the first visit to a new site on a Node.js server, set its public address in the EmDash integration or the host’s environment. Here, yoursite.com stands for your own domain:
emdash({
database: sqlite({ url: "file:./data.db" }),
storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file" }),
siteUrl: "https://yoursite.com",
})
Or set the environment value:
EMDASH_SITE_URL=https://yoursite.com
Without it, a Node.js production build refuses setup with SITE_URL_REQUIRED, even on localhost. Local astro dev and production Cloudflare Workers can run setup without this value.
Build the site and start the server:
npm run build
node --env-file=.env ./dist/server/entry.mjs
The built server does not load .env by itself, and the template’s npm start script runs it without --env-file. Pass the file as above, or set EMDASH_ENCRYPTION_KEY in your host’s environment.
Your SQLite file and uploads folder need a persistent disk. Back up both, along with your encryption key. If you use registry plugins, include the Node.js sandbox packages and configuration described above when setting up this server.
Open https://yoursite.com/_emdash/admin and run the setup wizard on your live address to create a passkey for that domain.
Cloudflare notes
Choose Cloudflare Workers when creating the project, or use --template cloudflare:blog. The template’s wrangler.jsonc binds a D1 database as DB and an R2 bucket as MEDIA, and includes a cron trigger for scheduled publishing.
- Before the first deploy, rename
name,database_nameandbucket_name. The template usesmy-emdash-siteandmy-emdash-media, whatever you called your project. Wrangler creates resources by name on the first deploy and reuses a name that already exists in your account. - If you want registry plugins, turn on the Worker Loader binding described above and use the Workers Paid plan.
- Log in, deploy and set the encryption key:
sh
npx wrangler login
npm run deploy # astro build && wrangler deploy
npx wrangler secret put EMDASH_ENCRYPTION_KEY
- Open the admin on your live domain and run the setup wizard there, so your passkey belongs to that address.
Cloudflare can take up to 15 minutes to start running a new cron trigger. We did not deploy to Cloudflare for this guide: these commands and configuration notes come from the template and the EmDash Cloudflare guide.
You now have the steps to build the blog shown in the video and prepare it for hosting. For a finished design, explore Peachfin’s Astro themes. You can find Comment Spam Protection in the EmDash registry, read its plugin details, or explore Auto Unpublish Posts.