Views
On this page 11
Stacks uses STX for views and components. STX combines server rendering, reactive client code, component composition, and scoped styles in .stx files.
Application views live in resources/views/. Reusable components, layouts, and partials live in their matching directories under resources/.
Create a view
Create resources/views/welcome.stx:
<scriptserver
const pageTitle = 'Welcome to Stacks'
</script
<script
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() {
count.value++
}
</script
<template
<mainclass=""
<h1class=""
{{ pageTitle }}
</h1
<buttonclass=""click=""
Count: {{ count }}
</button
<pclass=""
Doubled: {{ doubled }}
</p
</main
</template
Browser auto-imports make ref, computed, watch, and the supported composables available inside STX scripts. Do not use direct document or window access. Keep client behavior in signals, composables, directives, and component methods.
Rendering data
Double braces escape interpolated values:
<p{{ user.name }}</p
<p{{ items.length }} items</p
Use the raw-output form only for trusted HTML:
<div{!! trustedHtml !!}</div
Server scripts run before the template is rendered and can prepare data for the page:
<scriptserver
const products = await Product.where('status', 'published').all()
</script
<template
<ul
@foreach(products as product)
<li{{ product.name }}</li
@endforeach
</ul
</template
Conditionals and loops
Use Blade-style directives for server-rendered control flow:
@if(user)
<pWelcome back, {{ user.name }}</p
@else
<ahref=""Sign in</a
@endif
@foreach(posts as post)
<article
<h2{{ post.title }}</h2
</article
@endforeach
Use @for and @while when an indexed loop or condition is a better fit:
@for(let index = 0; index < featured.length; index++)
<p{{ index + 1 }}. {{ featured[index].name }}</p
@endfor
Components
Components live in resources/components/ and are auto-resolved by name. A component at resources/components/UserCard.stx can be used directly:
<UserCarduser=""compact
Declare typed props inside the component:
<script
interface Props {
user: {
name: string
email: string
}
compact?: boolean
}
const props = defineProps<Props()
</script
<template
<articleclass=""
<h2class=""{{ props.user.name }}</h2
@unless(props.compact)
<pclass=""{{ props.user.email }}</p
@endunless
</article
</template
Events and state
Bind component methods with event directives:
<script
const open = ref(false)
function toggle() {
open.value = !open.value
}
</script
<template
<buttonclick=""
{{ open ? 'Hide details' : 'Show details' }}
</button
@if(open)
<pAdditional details</p
@endif
</template
For shared behavior, place a function or composable in resources/functions/. Browser auto-import generation makes exported functions available to templates after buddy generate.
Slots
Slots let a component accept caller-provided content:
<!-- resources/components/Card.stx -->
<template
<sectionclass=""
<headerclass=""
<slotname=""
</header
<slot
</section
</template
<Card
<templateheader
<h2Account</h2
</template
<pManage your profile and security settings</p
</Card
Layouts and partials
Layouts live in resources/layouts/. Select one with frontmatter or the layout directive supported by your application configuration. Partials live in resources/partials/ and can be included from a view:
@include('partials/header')
<main
{{ content }}
</main
@include('partials/footer')
Pass values to a partial when it needs local context:
@include('partials/account-menu', { user })
Styling
Use Crosswind utilities in templates. Component styles can be scoped when custom CSS is necessary:
<template
<divclass=""
<slot
</div
</template
<stylescoped
.profile-card {
container-type: inline-size;
}
</style
Prefer Crosswind transitions and CSS keyframes for motion. Use usePreferredReducedMotion() before enabling non-essential animation.
Configuration
STX configuration lives in config/ui.ts:
import type { StxOptions } from '@stacksjs/stx'
export default {
componentsDir: 'components',
layoutsDir: 'layouts',
partialsDir: 'partials',
} satisfies StxOptions
The bun-plugin-stx plugin compiles .stx files during development and production builds.
Commands
buddy make:view account
buddy make:component UserCard
buddy dev
buddy build
buddy generate
Use buddy make:page as an alias for buddy make:view. Run buddy generate after adding browser functions or components that should appear in generated auto-import types.