Dashboard

Bridge

Go-JS bridge for calling Go functions from the dashboard UI via Alpine.js

Overview

The dashboard includes a Go-JS bridge powered by ForgeUI's bridge system. It enables the dashboard UI to call Go functions directly from the browser using Alpine.js magic helpers ($go, $goBatch, $goStream) or the ForgeBridge JavaScript client.

The bridge is enabled by default (EnableBridge: true) and provides 8 built-in dashboard functions. Extensions can register custom functions to expose any Go logic to the dashboard UI.

How It Works

  1. Go functions are registered with the bridge (server-side)
  2. The browser calls functions via POST {basePath}/bridge/call or SSE streaming via GET {basePath}/bridge/stream/
  3. Alpine.js magic helpers abstract the HTTP calls into simple async functions
  4. Responses are JSON-encoded and returned to the browser

Built-in Functions

The dashboard registers these functions automatically:

FunctionParametersReturnsCacheDescription
dashboard.getOverviewnone*collector.OverviewData10sApplication overview: health, uptime, metrics
dashboard.getHealthnone*collector.HealthData5sHealth check results
dashboard.getMetricsnone*collector.MetricsData10sCurrent metric values
dashboard.getServicesnone[]collector.ServiceInfo10sRegistered services list
dashboard.getServiceDetail{name: string}*collector.ServiceDetailnoneDetailed info for a specific service
dashboard.getHistorynonecollector.HistoryData5sHistorical data points
dashboard.getMetricsReportnone*collector.MetricsReport10sComprehensive metrics report
dashboard.refreshnone*collector.OverviewDatanoneForce data refresh and return overview

Registering Custom Functions

Via Extension API

dashExt := ext.(*dashboard.Extension)

err := dashExt.RegisterBridgeFunction("myapp.getUsers", func(ctx bridge.Context, params GetUsersParams) (*UsersResult, error) {
    // Query database, call service, etc.
    users, err := userService.List(ctx.Context(), params.Limit)
    if err != nil {
        return nil, err
    }
    return &UsersResult{Users: users}, nil
}, bridge.WithDescription("List application users"))

Via DashboardBridge

db := dashExt.DashboardBridge()

err := db.Register("myapp.getStats", func(ctx bridge.Context, params EmptyParams) (*Stats, error) {
    return collectStats(), nil
},
    bridge.WithDescription("Get application statistics"),
    bridge.WithFunctionCache(10 * time.Second),
)

Function Signature

Bridge function handlers follow the pattern:

func(ctx bridge.Context, params T) (R, error)
  • ctx -- bridge context with request metadata and a Context() method for the standard context.Context
  • params T -- any struct that can be JSON-decoded from the request. Use struct{} for no parameters.
  • R -- any type that can be JSON-encoded as the response
  • error -- returned errors are sent to the client as error responses

Function Options

OptionDescription
bridge.WithDescription(desc)Human-readable description of the function
bridge.WithFunctionCache(ttl)Cache responses for the given duration. Subsequent calls within the TTL return the cached result.

JavaScript Client Usage

Alpine.js Magic Helpers

In any Alpine.js component within the dashboard, use the $go magic helper:

// Single function call
const overview = await $go('dashboard.getOverview')

// With parameters
const detail = await $go('dashboard.getServiceDetail', { name: 'api-gateway' })

// Custom function
const users = await $go('myapp.getUsers', { limit: 50 })

Batch Calls

Call multiple functions in a single HTTP request:

const [overview, health, metrics] = await $goBatch([
    { fn: 'dashboard.getOverview' },
    { fn: 'dashboard.getHealth' },
    { fn: 'dashboard.getMetrics' },
])

Streaming

For long-running operations, use streaming over SSE:

await $goStream('myapp.streamLogs', { service: 'api' }, (chunk) => {
    console.log('received:', chunk)
})

Bridge Endpoints

MethodPathDescription
POST{basePath}/bridge/callCall a bridge function. Request body: {"fn": "name", "params": {...}}. Response: {"data": ..., "error": null}
GET{basePath}/bridge/stream/Streaming responses via SSE

These endpoints are served automatically by ForgeUI when the bridge is enabled.

CSRF protection at the forge router level handles security for bridge calls. The bridge itself has CSRF disabled (bridge.WithCSRF(false)) to avoid double-checking.

Disabling the Bridge

dashboard.NewExtension(
    dashboard.WithBridge(false),
)

When disabled, DashboardBridge() returns nil, RegisterBridgeFunction() returns an error, and bridge endpoints are not mounted.

How is this guide?

On this page