Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 34 additions & 2 deletions packages/cli/docs/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,35 @@ quire pdf --build --engine prince --output final-print.pdf

---

## Serving the Built Site

Preview your built publication without live-reload or file watching:

```bash
# Serve the built site (requires prior `quire build`)
quire serve

# Build first if needed, then serve
quire serve --build

# Use a custom port
quire serve --port 3000

# Open browser automatically
quire serve --build --open
```

### When to Use `serve` vs `preview`

| Command | Use Case |
|---------|----------|
| `quire preview` | Active development with live-reload |
| `quire serve` | Final review of built output before deployment |

The `serve` command starts a lightweight static file server for `_site/` without Eleventy's development overhead. Use it to verify the final build before deploying.

---

## Generating EPUB

Create an e-book version of your publication:
Expand Down Expand Up @@ -167,10 +196,13 @@ quire clean
# 2. Build the HTML site
quire build

# 3. Generate PDF
# 3. Review the built site locally
quire serve --open

# 4. Generate PDF
quire pdf --open

# 4. Generate EPUB
# 5. Generate EPUB
quire epub --open
```

Expand Down
25 changes: 25 additions & 0 deletions packages/cli/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import Command from '#src/Command.js'
import { Option } from 'commander'
import { withOutputModes } from '#lib/commander/index.js'
import { api, cli } from '#lib/11ty/index.js'
import { serve } from '#lib/server/index.js'
import processManager from '#lib/process/manager.js'
import paths from '#lib/project/index.js'
import { clean } from '#helpers/clean.js'
import open from 'open'
import { recordStatus } from '#lib/conf/build-status.js'
import reporter from '#lib/reporter/index.js'
import testcwd from '#helpers/test-cwd.js'
Expand All @@ -25,6 +28,8 @@ export default class BuildCommand extends Command {
helpText: `
Examples:
quire build Build the site
quire build --serve Build and start static server
quire build --open Build, serve, and open browser
quire build --verbose Build with detailed progress
quire build --debug Build with debug output

Expand All @@ -34,6 +39,9 @@ Note: Run before "quire pdf" or "quire epub" commands.
options: [
[ '-d', '--dry-run', 'run build without writing files' ],
[ '--dryrun', 'alias for --dry-run', { hidden: true, implies: { dryRun: true } } ],
[ '--serve', 'start static server after build', { conflicts: 'dryRun' } ],
[ '-p, --port <port>', 'server port', { default: 8080, implies: { serve: true } } ],
[ '--open', 'open in default browser after build', { implies: { serve: true } } ],
// Use Option object syntax to configure this as a hidden option
new Option('--11ty <module>', 'use the specified 11ty module')
.choices(['api', 'cli']).default('api').hideHelp(),
Expand Down Expand Up @@ -63,6 +71,23 @@ Note: Run before "quire pdf" or "quire epub" commands.
recordStatus(paths.getProjectRoot(), 'build', 'failed')
throw error
}

// Start static server after build if --serve flag is set
if (options.serve) {
const port = parseInt(options.port, 10)

const { url, stop } =
await serve(paths.getSitePath(), { port, quiet: options.quiet, verbose: options.verbose })

processManager.onShutdown('serve', stop)

try {
if (options.open) open(url)
await new Promise(() => {})
} finally {
processManager.onShutdownComplete('serve')
}
}
}

preAction(thisCommand, actionCommand) {
Expand Down
Loading