Skip to main content

Project Structure

A lua-spa project created with lua-spa create my_app looks like this:

my_app/
├── index.lspa ← HTML shell (root page)
├── spa.config.json ← app config (title, port, entry component, router)
├── index.css ← global styles
├── components/ ← all .lspa components live here
│ ├── App.lspa
│ ├── App.css
│ └── ...
└── static/ ← static assets (images, icons)
└── logo.png

File roles

index.lspa

The HTML shell. lua-spa fills these placeholders at build time:

PlaceholderValue
{{ SPA_PAGE_TITLE }}page_title from config
{{ SPA_MOUNT_ID }}mount_id from config (default app)
{{ SPA_OUTLET }}Server-rendered HTML of the entry component
{{ SPA_BOOTSTRAP }}Component registry JSON + runtime JS

spa.config.json

{
"page_title": "my_app",
"initial_props": {},
"server": {
"host": "127.0.0.1",
"port": 8000
}
}

Optional fields: entry_component, mount_id, router.

components/

Every .lspa file is a component. Each file contains up to three sections:

@import Child from './Child/Child.lspa'

<python>
... server + client logic
</python>

<style src="./App.css"></style>

<template>
... HTML with {{ }} and directives
</template>

static/

Static assets are served at /static/<filename>. Reference them in templates as src="/static/logo.png".