This document provides detailed instructions for developing applications using the WebStack framework.
WebStack is designed to be a versatile Go-based framework that supports:
- Server-side rendering (SSR)
- Client-side reactivity
- REST API endpoints
- gRPC services
-
Web Application (
/api/web
)- Uses
templ
for server-side templating - HTMX for dynamic server interactions
- Petite Vue (6kb) for client-side reactivity
- Go's
embed
feature for static assets
- Uses
-
REST Server (
/api/rest
)- Traditional REST API endpoints
- JSON response handling
- Middleware support
-
gRPC Server (
/api/rpc
)- Protocol buffer definitions
- gRPC service implementations
- Binary communication
To create a new web application (e.g., admin panel):
-
Create a new directory under
/api
:mkdir -p api/admin
-
Create the necessary folder structure:
api/admin/ ├── handlers/ ├── templates/ ├── static/ └── embed.go
-
Implement the
embed.go
file:package admin import "embed" //go:embed all:static templates var content embed.FS
Use templ
for server-side components:
// example.templ
package templates
templ UserProfile(user User) {
<div class="profile">
<h1>{user.Name}</h1>
<div hx-get="/api/user/details" hx-trigger="load">
Loading...
</div>
</div>
}
Use Petite Vue for reactive components:
<div v-scope="{ count: 0 }">
<button @click="count++">Increment</button>
<span>{{ count }}</span>
</div>
-
Component Organization
- Keep templates in
/templates
directory - Organize by feature/module
- Use partial templates for reusability
- Keep templates in
-
State Management
- Use Petite Vue for local state
- Server state via HTMX requests
- Keep client-side state minimal
-
Performance
- Leverage SSR for initial load
- Use HTMX for dynamic updates
- Minimize client-side JavaScript
-
Security
- Implement CSRF protection
- Validate all inputs
- Use secure headers
- Start with server-side templates
- Add HTMX interactions
- Include Petite Vue where needed
- Test thoroughly
- Deploy using Go's build system
<form hx-post="/api/submit" hx-swap="outerHTML">
<input type="text" name="username" v-model="form.username">
<button type="submit">Submit</button>
</form>
<div hx-get="/api/data" hx-trigger="revealed">
Loading...
</div>
<div v-scope="{ items: [] }" @mounted="fetchItems()">
<ul>
<li v-for="item in items">{{ item.name }}</li>
</ul>
</div>