Interaction

Server-Rendered Updates

Return HTML fragments and Turbo responses from controller actions.

By Guillermo Alvarez - Published - Updated

Keep routes useful without JavaScript

Start with a normal controller action:

func (c *PostsController) Show(
    _ http.ResponseWriter,
    r *http.Request,
) error {
    post, ok := c.posts.Get(r.PathValue("post_id"))
    if !ok {
        return lazycontroller.Error(http.StatusNotFound, fmt.Errorf("post not found"))
    }

    c.Set("post", post)
    return nil
}

The route renders a full page for ordinary browser navigation.

Render the same data into a frame

If the browser targets a Turbo frame, GoLazy renders the frame response instead of the whole layout:

func (c *PostsController) Show(_ http.ResponseWriter, _ *http.Request) error {
    c.Set("post", post)
    c.SetTurboFrameOptions(lazyturbo.Loading("lazy"))
    return c.Render("show")
}

The template can include a full-page view and a frame partial:

app/views/posts/show.html.tpl
app/views/posts/post_frame.html.tpl

Return small HTML updates

For non-frame endpoints, render without a layout:

func (c *PostsController) Row(_ http.ResponseWriter, _ *http.Request) error {
    c.NoLayout()
    c.Set("post", post)
    return c.Render("row")
}

The route still uses controller data and templates, but returns only the HTML fragment the interaction needs.