Basic Usage
On this page 11
This guide will help you get started with stx by walking through the basics of creating templates and components.
Creating Your First Template
Create a new file pages/hello.stx:
<!DOCTYPE html>
<htmllang="">
<head>
<title>Hello stx</title>
<metacharset="">
<metaname=""content="">
</head>
<body>
const greeting = 'Hello, World!'
const items = ['stx', 'is', 'awesome']
const isLoggedIn = true
<divclass="">
<h1class="">{{ greeting }}</h1>
@if(isLoggedIn)
<pclass="">Welcome back</p>
<ulclass="">
@foreach(itemsasitem)
<liclass="">{{ item }}</li>
</ul>
</div>
</body>
</html>
Basic Syntax
Variables and Expressions
Use double curly braces for variable interpolation:
<p>Hello, {{ name }}</p>
<span>Total: {{ price * quantity }}</span>
<divclass="">
<h2>{{ user.name }}</h2>
<span>{{ user.email }}</span>
</div>
Use the @ts directive for TypeScript code:
interface User {
name: string
email: string
isAdmin: boolean
}
const user: User = {
name: 'John',
email: 'john@example.com',
isAdmin: true
}
<divclass="">
<h1>Welcome, {{ user.name }}</h1>
<p>{{ user.email }}</p>
@if(userisAdmin)
<admin-badge>Admin User</admin-badge>
</div>
Conditionals
stx provides powerful conditional directives:
@if(userisAdmin)
<admin-panelclass="">
<h2>Admin Dashboard</h2>
<user-management />
</admin-panel>
<user-dashboardclass="">
<h2>User Dashboard</h2>
<user-profile />
</user-dashboard>
@unless(userisBlocked)
<divclass="">
<button@click="sendMessage">Send Message</button>
</div>
@switch(userrole)
@case('')
<admin-view />
@case('')
<moderator-view />
<user-view />
Loops
stx offers various looping constructs:
<ulclass="">
@foreach(usersasuser)
<liclass="":key="user">
<user-card:user="user" />
</li>
</ul>
<divclass="">
@foreach(itemsasitemindex)
<divclass=""x-style="">
{{ item.name }}
</div>
</div>
@forelse(notificationsasnotification)
<notification-item:data="notification" />
<empty-state>No notifications found</empty-state>
Creating Components
Components help you create reusable UI elements. Create a new file components/Button.stx:
interface ButtonProps {
type?: 'primary' | 'secondary' | 'danger'
size?: 'sm' | 'md' | 'lg'
disabled?: boolean
onClick?: () => void
}
const variants = {
primary: 'bg-blue-500 hover:bg-blue-600 text-white',
secondary: 'bg-gray-500 hover:bg-gray-600 text-white',
danger: 'bg-red-500 hover:bg-red-600 text-white'
}
const sizes = {
sm: 'px-2 py-1 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg'
}
@component(''
props: {
type: 'primary',
size: 'md',
disabled: false,
onClick: () => {}
}
})
<button
class="button {{ variants[type] }} {{ sizes[size] }} rounded-md font-medium transition-colors"
x-disabled="disabled"
="onClick"
>
<slot></slot>
</button>
<style>
.button {
display: inline-flex;
align-items: center;
justify-content: center;
border: none;
cursor: pointer;
}
.button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style>
Using Components
Import and use components in your templates:
{ Button } from '../components/Button'
<divclass="">
<Button
type="primary"
size="lg"
="handleSubmit"
>
Submit Form
</Button>
<Button
type="secondary"
size="md"
="handleCancel"
>
Cancel
</Button>
<Button
type="danger"
size="md"
x-disabled="isLoading"
>
{{ isLoading ? 'Loading...' : 'Delete' }}
</Button>
</div>
Layouts
Create reusable layouts with @extends and @section:
- Create a layout (
layouts/main.stx):
<!DOCTYPE html>
<htmllang="">
<head>
<metacharset="">
<metaname=""content="">
<title>@yield('') - My App</title>
@section('')
<linkrel=""href="">
</head>
<body>
<navclass="">
@include('')
</nav>
<mainclass="">
@section('')
<p>No content provided</p>
</main>
<footerclass="">
@include('')
</footer>
@section('')
<script></script>
</body>
</html>
- Use the layout in a page:
@extends('')
@section('', '')
@section('')
<linkrel=""href="">
@section('')
<divclass="">
<h1class="">Welcome to Dashboard</h1>
<divclass="">
@foreach(widgetsaswidget)
<dashboard-widget:data="widget" />
</div>
</div>
TypeScript Integration
stx provides first-class TypeScript support:
interface User {
id: number
name: string
email: string
role: 'admin' | 'user' | 'moderator'
lastActive: Date
}
const users: User[] = [
{
id: 1,
name: 'John Doe',
email: 'john@example.com',
role: 'admin',
lastActive: new Date()
},
{
id: 2,
name: 'Jane Smith',
email: 'jane@example.com',
role: 'moderator',
lastActive: new Date()
}
]
function formatDate(date: Date): string {
return new Intl.DateTimeFormat('en-US').format(date)
}
<divclass="">
@foreach(usersasuser)
<divclass="":key="user">
<divclass="">
<h3class="">{{ user.name }}</h3>
<spanclass="{{user}}">
{{ user.role }}
</span>
</div>
<divclass="">
<pclass="">{{ user.email }}</p>
<pclass="">
Last active: {{ formatDate(user.lastActive) }}
</p>
</div>
@if(userrole=== '')
<divclass="">
<admin-controls:user-id="user" />
</div>
</div>
</div>
Development Workflow
- Start the development server:
bun run dev
- Build for production:
bun run build
- Preview production build:
bun run preview
Next Steps
- Learn about Components in depth
- Explore Directives for template control
- Understand TypeScript Integration
- Check out the VSCode Extension for better development experience