pb_ssr

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2026 License: MIT Imports: 25 Imported by: 0

README

PocketBase server-side rendering utilities

PocketBase allows to have a complete backend (database, authentication, file storage, etc.) in a single executable. The author of PocketBase strongly recommends to use PocketBase with a Single Page Application (SPA) and says that it is not well suited for server-side rendering for now.

This package goes against the author's recommendation and provides utilities for server-side rendering of PocketBase applications. In combination with htmx or Unpoly you can have a dynamic frontend, without the hassle of SPA nor a complex backend.

It provides:

  • Helpers to render HTML pages
  • User management (account creation, login, logout, etc.) with default templates
  • Cross-Origin Request Forgery (CSRF) protection with Sec-Fetch-Site header
  • Internationalization (English, French, German, Spanish)
  • OAuth2 authentication

How to use

See examples/basic.go for a simple example with no configuration.

Create a Go project with PocketBase as described in the official documentation.

Instantiate pb_ssr and add the default routes. Add pb_ssr.RegisterRoutes(se) and you are ready to go. Some default views and routes are provided to get started.

⚠️There is no rate limiting by default (contrary to PocketBase’s API)

Use PocketBase’s go extension to add routes, middlewares and interact with the database.

Use PB-SSR to render HTML pages with the render functions. The template language is Go's html/template.

By default, the following templates are provided:

  • layout.html
  • change-password.html
  • forgot-password.html
  • login.html
  • register.html
  • reset-password.html
  • index.html

They provide an immediate available authentication system. The text is localized, but not styled.

You can override any of those templates by placing your own in a views directory.

You probably want to override at least layout.html and index.html

OAuth

The OAuth providers are configured in the PocketBase admin panel. Available providers are exposed in the template as .oauthProviders (a []string).

To connect, link to /oauth/provider_name and configure your OAuth provider’s callback URL to /oauth/callback.

Global Data

Pass values that will always be available in all views:

ssr.SetGlobal("appName", "My App").SetGlobal("version", "1.0")

Access them in templates: {{ .globals.appName }}

Flash Messages

Set flash messages that will be displayed on the next page load:

SetFlashSuccess(w, "Account created successfully!")
SetFlashError(w, "Something went wrong.")

Access in templates:

{{ if .flashSuccess }}
<div class="success">{{ .flashSuccess }}</div>
{{ end }}
{{ if .flashError }}
<div class="error">{{ .flashError }}</div>
{{ end }}

The flash messages are stored in short-lived cookies, which allows to keep them across redirections.

The Render function

The Render function will load all the data and expose them in the template. Data automatically loaded by the Render function and exposed in the template are:

  • .globals: the global variables set by ssr.SetGlobal
  • .flashSuccess: the success flash message
  • .flashError: the error flash message
  • .user: the current user
  • .locale: the current locale
  • .oauthProviders: the configured OAuth providers
  • .data: a map, parameter of the Render function
  • .errors: a map, parameter of the Render function
Templates caching

We try to detect if the program is running in development mode. If it is, we disable caching of templates so that changes are immediately visible.

It can be forced by setting the PB_SSR_DEV environment variable to true or 1. Any other value will disable caching.

Configuration

NewConfig allows a finer control over the configuration to set the following parameters:

  • locale: the default locale
  • passwordMinLength: the minimum length of the password
  • collectionName: the name of the collection to use for users
  • redirectURL: the URL to redirect to after login
CSRF Protection

Cross-Site Request Forgery (CSRF) happens when another site makes a request on behalf of the user to another site.

To protect against that attack, any data-modifying request (POST, PUT, DELETE) reads the Sec-Fetch-Site header. It must be same-origin or same-site.

Previously, the practice was to use a cookie and a token, but the header is considered as Widely available since March 2023.

The future

There are many things that could be improved:

  • allow more customization of everything
  • handle partial views
  • support for login by email
  • dynamic locale
  • maybe implicit declaration of views based on the routes?
  • 403, 404, 500 pages
  • default rate limiting
  • return partial views aware of htmx or unpoly frames
  • use PocketBase’s API access rules to control access to data
  • get feedback from you ;)

PocketBase’s author is planning a refactor that might include some tools that would make this package obsolete.

LLM used on this project

I used this project to test LLM’s to see if and how they could assist me. This is why some commits are a bit messy. But blame me for the design decisions (or tell how it could be improved).

License

This project is licensed under the MIT License.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClearAuthCookie

func ClearAuthCookie(w http.ResponseWriter)

func GetAndClearErrorFlashMessage

func GetAndClearErrorFlashMessage(w http.ResponseWriter, r *http.Request) string

func GetAndClearOAuthStateCookie

func GetAndClearOAuthStateCookie(w http.ResponseWriter, r *http.Request) (state, provider string)

func GetAndClearSuccessFlashMessage

func GetAndClearSuccessFlashMessage(w http.ResponseWriter, r *http.Request) string

func LoadAuthCookie

func LoadAuthCookie(e *core.RequestEvent) error

func SetAuthCookie

func SetAuthCookie(w http.ResponseWriter, token string)

Auth cookies

func SetFlashError

func SetFlashError(w http.ResponseWriter, message string)

func SetFlashSuccess

func SetFlashSuccess(w http.ResponseWriter, message string)

func SetOAuthStateCookie

func SetOAuthStateCookie(w http.ResponseWriter, state, provider string)

OAuth cookies

Types

type Config

type Config struct {
	// contains filtered or unexported fields
}

func New

func New(locale string) *Config

func NewConfig

func NewConfig(locale string, passwordMinLength int, collectionName string, redirectURL string) *Config

func (*Config) ChangePasswordHandler

func (c *Config) ChangePasswordHandler(e *core.RequestEvent) error

func (*Config) ForgotPasswordHandler

func (c *Config) ForgotPasswordHandler(e *core.RequestEvent) error

func (*Config) Locales

func (c *Config) Locales(fsys fs.FS)

func (*Config) LoginHandler

func (c *Config) LoginHandler(e *core.RequestEvent) error

func (*Config) MakeHandler

func (c *Config) MakeHandler(f func(c *Config, e *core.RequestEvent) error) func(e *core.RequestEvent) error

Transforms a function into a handler that can be used with the core.RequestEvent

func (*Config) OAuthCallbackHandler

func (c *Config) OAuthCallbackHandler(e *core.RequestEvent) error

func (*Config) OAuthInitHandler

func (c *Config) OAuthInitHandler(e *core.RequestEvent) error

func (*Config) RegisterHandler

func (c *Config) RegisterHandler(e *core.RequestEvent) error

func (*Config) RegisterRoutes

func (c *Config) RegisterRoutes(se *core.ServeEvent)

func (*Config) Render

func (c *Config) Render(e *core.RequestEvent, file string, params, errors map[string]any) error

func (*Config) RenderHandler

func (c *Config) RenderHandler(file string) func(e *core.RequestEvent) error

func (*Config) ResetPasswordFormHandler

func (c *Config) ResetPasswordFormHandler(e *core.RequestEvent) error

func (*Config) ResetPasswordHandler

func (c *Config) ResetPasswordHandler(e *core.RequestEvent) error

func (*Config) SetGlobal

func (c *Config) SetGlobal(key string, value any) *Config

Set a global variable that will be available in all templates This function is chainable.

func (*Config) VerifyCrossOrigin

func (config *Config) VerifyCrossOrigin(e *core.RequestEvent) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL