EN FR

Chapter 03Get started

Local setup

From an empty machine to the first publish, with no remote repository and no host. Three terminals, one key, ten minutes.

7 min read14 sectionsChapter 3 / 22

Requirements

ToolVersionWhy
Node.js20 or later (developed on 22.14)Astro 5, and the web APIs the functions use.
npm10 or laterShips with Node. npm create and workspaces.
Gitany recent versionTo version the site. Not needed for the local trial.
A Git repository reachable by APIGitHubOnly to publish online. A fake local service is provided.
check bash
node -v     # v20.x or later
npm -v
Windows

Everything works in PowerShell as well as Git Bash. Commands in this documentation use POSIX syntax; under PowerShell replace VAR=value command with $env:VAR = 'value'; command, and && with ;.

Three ways to start

The usual case

A new site

npm create inline@latest my-site — scaffold, theme, checks, key. That is the path described below.

To work on the tool

The reference repository

Clone the inline repository itself: it contains inline-core and a bilingual example site.

Existing Astro site

Add the integration

npm install inline-core then four route adapters. See below.

1. Create the site

terminal bash
npm create inline@latest martin-bakery -- \
  --nom "Martin Bakery" \
  --courriel contact@martin-bakery.com \
  --langue en

cd martin-bakery
npm install
OptionDefaultRole
--nomfolder nameSite name, shown in the footer and the help page.
--courrielcontact@exemple.frContact address shown to the client when they need help.
--languefrMain language code. Two lowercase letters.

The command refuses to write into an existing, non-empty folder. It produces:

what is written text
martin-bakery/
  astro.config.mjs          inline integration, static output, i18n
  package.json              dev, build, serve:functions, mock:git, make:key, check
  wrangler.toml             host configuration (functions)
  .gitignore                node_modules, dist, .astro, .dev.vars…
  .env.example              the ONLY versioned environment file
  .dev.vars                 local trial credentials — ignored by Git
  functions/api/*.ts        four route adapters
  scripts/                  check-html, check-locales, check-logs, check-secrets,
                            make-key, mock-git-api
  src/
    content/config.ts       collection declaration
    content/site.json       navigation, contact details, footer
    content/pages/en/home.json
    components/Testimonial.astro
    layouts/Base.astro
    lib/locales.ts          the languages of THIS site
    pages/[lang]/[...slug].astro
    styles/theme.css        the theme — the file to adapt
  .github/workflows/ci.yml  automated checks
What it does not write

No editing logic: no overlay, no schema, no identity check, no server route. All of that comes from inline-core, as a versioned dependency. That is the whole difference between scaffolding and copy-paste — on the day of a security fix, npm update inline-core is enough.

The key, shown once

At the end, the command prints the site key. It is already written into .dev.vars for local use, but it is stored nowhere in readable form on the server: only its argon2id hash exists. A lost key is regenerated, never recovered.

2. Start the three processes

Three terminals, at the project root:

  1. The fake Git repository

    bash bash
    npm run mock:git

    Listens on http://127.0.0.1:8787 and mimics the two GitHub Contents API routes actually used. Publishing writes straight into the project files, as a commit would. Development aid only.

  2. The build

    bash bash
    npm run build

    Builds dist/. The build fails if content does not pass the schema, or if a data-cms points at a missing key — deliberately.

  3. The site and the functions

    bash bash
    npm run serve:functions

    Serves dist/ and /functions on http://127.0.0.1:8788. This is where editing happens.

The number one setup trap

npm run dev starts the Astro server alone: the site appears, but /api/* does not exist, so /admin cannot open a session and editing does not work. To edit you need npm run serve:functions. npm run dev is for working on layout, not on editing.

3. First change

  1. Open http://127.0.0.1:8788/admin.
  2. Paste the key printed at creation time, submit.
  3. You land on the site, with a bar at the bottom of the screen.
  4. Click a heading: it becomes editable, a variants toolbar appears.
  5. Change the text, then click Publish.

With the fake repository, publishing writes to src/content/pages/en/home.json. Run npm run build again to see the change frozen into the HTML — in production the host does that on its own.

The journey, without installing anything

The simulator reproduces exactly that journey inside this documentation: key, overlay, editing, publishing, conflict. Useful to show the tool before installing it.

Ports in use

PortProcessRole
4321npm run devAstro server alone — layout, no editing.
8788npm run serve:functionsBuilt site + functions. This is the editing address.
8787npm run mock:gitFake local Git service. Change with MOCK_PORT.

The .dev.vars file

This is the local environment file, ignored by Git, never deployed. It is written by the create command and looks like this:

.dev.vars env
# Local trial only. Ignored by Git, never deployed.
EDITOR_KEY_HASH=$argon2id$v=19$m=19456,t=2,p=1$<salt>$<digest>
SESSION_SECRET=<at least 32 characters>
EDITOR_NAME=Site editor
EDITOR_EMAIL=contact@martin-bakery.com
GIT_PROVIDER=github
GIT_REPO=agency/martin-bakery
GIT_BRANCH=main
GIT_TOKEN=local-trial
GIT_API_BASE=http://127.0.0.1:8787

GIT_API_BASE is the line that switches to the fake repository. Removing it makes the function talk to the real GitHub — with a real GIT_REPO and GIT_TOKEN. Detail of every variable: Reference.

Never in the repository

.dev.vars, .env and any real environment file are ignored by Git. The only versioned environment file is .env.example, which contains no values. npm run check additionally verifies that no secret ends up in the build folder.

Regenerating credentials

From the site — lost key, key to change

The key is stored nowhere in readable form: only its argon2id hash lives in an environment variable. So it is not recovered, it is regenerated — deliberately.

in the site project bash
npm run make:key

The command prints the new key, its hash and a session secret. Nothing is written to disk: whatever is not copied at that moment is lost. The rest — replacing the variables, redeploying, handing over — is in Security and authentication.

A site created before create-inline 1.1.0

The command only ships with the site as of that version; before it, it lived in the reference repository alone. Three lines catch it up: copy scripts/make-key.mjs from a recent site, then npm pkg set scripts.make:key="node scripts/make-key.mjs" and npm install --save-dev @noble/hashes — the hashing library does arrive in the tree through inline-core, but nothing guarantees it is hoisted to the root. Until then, rotation remains possible from the reference repository: same hash, same parameters.

From the reference repository — preparing a site

terminal bash
# Full credentials for a site: key, hash, session secret, variables, checklist
npm run create:site -- --nom "Martin Bakery" --depot agency/martin-bakery

# Same, plus writing a ready-to-use local .dev.vars
npm run create:site -- --nom "Local trial" --ecrire

create:site prints two blocks that do not travel together: what goes to the client (a key, an address) and what goes to the host (the hash, the secrets, the token), plus the pre-delivery checklist. See Operating.

In an existing Astro project

  1. Install the package

    bash bash
    npm install inline-core
  2. Declare the integration

    astro.config.mjs js
    import { defineConfig } from 'astro/config';
    import inline from 'inline-core/astro';
    
    export default defineConfig({
      output: 'static',
      integrations: [
        inline({
          locales: ['en'],                            // reference language first
          support: { email: 'contact@agency.com' },   // shown to the client
          // theme: 'src/styles/theme.css',           // default
          // pages: { admin: true, help: true },      // false to provide your own
        }),
      ],
    });

    The integration adds /admin and /aide, builds the overlay, injects the editing bootstrap, creates src/media/library.ts if missing, and refuses to start if output is not static.

  3. Write the four route adapters

    The host discovers routes from the /functions tree, outside the Astro build: an integration cannot inject them. Twenty lines, written once.

    functions/api/save.ts ts
    import { createSaveRoute } from 'inline-core/server';
    import { LOCALES } from '../../src/lib/locales';
    
    const route = createSaveRoute({ locales: LOCALES });
    
    export const onRequest = route.onRequest;
    export const onRequestPost = route.onRequestPost;

    The other three are identical with createAuthRoute(), createContentRoute({ locales }) and createUploadRoute(). Detail: Route reference.

  4. Declare the schema and the theme

    src/content/config.ts ts
    import { defineCollection } from 'astro:content';
    import { glob } from 'astro/loaders';
    import { pageSchema } from 'inline-core/schema';
    
    const pages = defineCollection({
      loader: glob({ pattern: '**/*.json', base: './src/content/pages' }),
      schema: pageSchema,
    });
    
    export const collections = { pages };
    src/layouts/Base.astro astro
    ---
    import 'inline-core/styles/tokens.css';
    import '../styles/theme.css';
    ---
  5. Generate a key

    Without EDITOR_KEY_HASH, editing is impossible — that is the default state. See Security.

Working on inline-core itself

The reference repository is an npm workspace: packages/inline-core and packages/create-inline are installed by link, and the site at the root consumes them directly.

terminal bash
git clone <repository> inline && cd inline
npm install

npm run create:site -- --nom "Local trial" --ecrire   # writes .dev.vars, prints the key
npm run build
npm run serve:functions

npm test          # the whole suite: git, auth, hardening, bootstrap, sanitising, media…
npm run check     # raw HTML, language parity, logs, secrets

To test the packages exactly as they would ship to a registry, see Operating (test:scaffold and test:pack).

If it does not start

SymptomLikely cause
/admin returns 404You are on npm run dev without building, or the integration is not declared.
The key is refused although it is right.dev.vars missing, or EDITOR_KEY_HASH empty. Variables are only re-read on (re)start.
“Incorrect key” after five attemptsThat is the rate limit: 5 attempts per quarter of an hour. It works.
Publishing fails locallynpm run mock:git is not running, or GIT_API_BASE is missing from .dev.vars.
The image does not appear after publishingThe file is in the repository, but the HTML has not been rebuilt. Run npm run build again.
Error “Charte introuvable” (theme not found)src/styles/theme.css is missing, or the theme option points elsewhere.

Full list: Troubleshooting and known traps.