Getting Started

This guide walks you through creating a Mage Pages site from scratch. By the end, you'll have a working site with multiple pages, a layout, and styled content.

Prerequisites

Install Deno if you haven't already:

curl -fsSL https://deno.land/install.sh | sh

Project Setup

Create a new directory and initialize it:

mkdir my-site && cd my-site
deno init

Create a deno.json with the required imports:

{
  "imports": {
    "@mage/app": "jsr:@mage/app",
    "preact": "npm:preact@^10"
  },
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "preact"
  }
}

Create the Server

Create main.ts:

import { MageApp } from "@mage/app";
import { pages } from "@mage/app/pages";

const app = new MageApp();
const { registerDevServer } = pages();

registerDevServer(app);

Deno.serve(app.handler);

Create Your First Page

Create a pages directory with an index page:

mkdir pages

Create pages/index.md:

---
title: "Home"
description: "Welcome to my site"
---

# Welcome

This is my site built with Mage Pages.

## Features

- Markdown content
- Automatic routing
- Fast development

Run the Development Server

deno run -A main.ts

Visit http://localhost:8000. You'll see your rendered markdown page.

Add More Pages

Create pages/about.md:

---
title: "About"
description: "About this site"
---

# About

This page is available at `/about`.

The file pages/about.md automatically becomes the /about URL.

Add a Layout

Layouts wrap your pages with consistent structure. Create pages/_layout.tsx:

import type { LayoutProps } from "@mage/app/pages";

export default function Layout(props: LayoutProps) {
  return (
    <div>
      <header>
        <nav>
          <a href="/">Home</a>
          <a href="/about">About</a>
        </nav>
      </header>
      <main>{props.children}</main>
      <footer>Built with Mage Pages</footer>
    </div>
  );
}

Refresh the page. Both / and /about now share the same header and footer.

Add Styles

Create a public directory for static assets:

mkdir public

Create public/styles.css:

body {
  font-family: system-ui, sans-serif;
  max-width: 800px;
  margin: 0 auto;
  padding: 2rem;
}

nav a {
  margin-right: 1rem;
}

Create pages/_html.tsx to include the stylesheet:

import type { HtmlTemplateProps } from "@mage/app/pages";

export default function Html(props: HtmlTemplateProps) {
  return (
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{props.title}</title>
        {props.description && (
          <meta name="description" content={props.description} />
        )}
        <link rel="stylesheet" href="/__public/styles-2755b33d.css" />
      </head>
      <body>{props.children}</body>
    </html>
  );
}

Project Structure

Your site now looks like this:

my-site/
├── pages/
│   ├── _html.tsx      # HTML document template
│   ├── _layout.tsx    # Root layout
│   ├── index.md       # → /
│   └── about.md       # → /about
├── public/
│   └── styles.css
├── deno.json
└── main.ts

Next Steps