How to add a static route

A static route is a page whose URL never changes. This guide covers adding one. For the mapping rules, see the routing reference.

Create the page file

Every .pk file in pages/ becomes a route. The directory structure determines the URL.

Create pages/about.pk:

<template>
  <piko:partial is="layout" :server.page_title="'About us'">
    <h1>About our company</h1>
    <p>Piko powers the site you are reading right now.</p>
  </piko:partial>
</template>

<script type="application/x-go">
package main

import (
    "piko.sh/piko"
    layout "myapp/partials/layout.pk"
)

func Render(r *piko.RequestData, props piko.NoProps) (piko.NoResponse, piko.Metadata, error) {
    return piko.NoResponse{}, piko.Metadata{
        Title: "About us | MyApp",
    }, nil
}
</script>

The page responds at http://localhost:8080/about once the dev server reloads.

Add nested static routes

Subdirectories translate to URL segments:

pages/
  company/
    about.pk       # /company/about
    team.pk        # /company/team
    careers.pk     # /company/careers

Piko needs no extra configuration. Each .pk file gets a route, and the file path determines the URL.

Use index.pk for directory base paths

To respond at /blog instead of only at /blog/something, create pages/blog/index.pk:

pages/
  blog/
    index.pk       # /blog
    {id}.pk        # /blog/{id}

Set the HTTP status

The page handler always writes 200 OK on a successful render. To return a non-200 status, return a typed error from piko. The router reads StatusCode() off any error implementing the piko.ActionError interface and writes the matching status:

func Render(r *piko.RequestData, props piko.NoProps) (piko.NoResponse, piko.Metadata, error) {
    return piko.NoResponse{}, piko.Metadata{}, &piko.GenericPageError{
        Status:  410,
        Message: "this page has been retired",
    }
}

The built-in error types (piko.NotFoundError for 404, piko.ForbiddenError for 403, piko.UnauthorisedError for 401, piko.BadRequestError for 400, piko.ValidationError for 422, piko.ConflictError for 409, piko.TeapotError for 418, and piko.GenericPageError for any other code) all satisfy piko.ActionError. See the error pages guide for customising the rendered error page.

Setting piko.Metadata{Status: 410} does not change the response in production. Only the test harness reads the field.

See also