SnappSnapp
  • Getting Started
  • Installation
  • Configuration
  • Styling
  • Introduction
  • Custom URLs
  • Authentication
  • Multi-Domain Architecture
  • Team Management
  • Third-Party Integrations
  • Metrics & Analytics
  • API Reference
  • English
  • Italiano
  • Getting Started
  • Installation
  • Configuration
  • Styling
  • Introduction
  • Custom URLs
  • Authentication
  • Multi-Domain Architecture
  • Team Management
  • Third-Party Integrations
  • Metrics & Analytics
  • API Reference
  • English
  • Italiano
  • Guide

    • Getting Started
    • Installation
    • Configuration
    • Styling

Overview

Snapp configuration is centralized in a single settings.yaml file.

Earlier versions split configuration across environment variables, database state, and partially hard-coded defaults. This made behavior opaque, hard to reason about, and error-prone. The current model intentionally collapses all runtime configuration into a single, validated document.

settings.yaml is now:

  • The only source of truth
  • Loaded at startup
  • Hot-reloaded at runtime
  • Strictly validated on every change
  • Backed by explicit defaults and fallbacks

The file is monitored via filesystem metadata (mtime). Any valid change is applied live without restarting the process or container.

Configuration file location

By default, Snapp reads /app/config/settings.yaml

In Docker deployments, this is typically mounted from: ./config/settings.yaml

If the file does not exist, Snapp will:

  1. Generate a minimal fallback configuration
  2. Start normally
  3. Persist the generated file to disk

Validation and fallback model

Configuration is parsed using a strict schema (Valibot).

Behavior on load:

  • Missing fields are filled using schema defaults
  • Invalid values reject the update
  • The last valid configuration remains active
  • Errors are logged, never silently ignored

This applies both at startup and during live reloads.

Minimal configuration

This is the smallest valid configuration.

appname: Snapp

admin:
  - email: admin@example.org
    username: admin

hosts:
  - origin: https://example.org

This configuration is sufficient to:

  • Bootstrap an admin account
  • Allow access from a single public origin
  • Run Snapp without optional integrations

Full configuration example

The following example represents all supported fields.

appname: Snapp

admin:
  - email: admin@example.org
    username: admin

hosts:
  - origin: https://auth.example.org
    options:
      customRedirect: /dashboard
      disable:
        homepage: false
        limits: true
        lowerCaseFallback: true
        signup: false
        twoFactor: true
      limits:
        maxSnappPerUser: 0
        requestsPerDay: 100
        requestsPerMinute: 14400
    thirdparty:
      umami:
        url: https://metrics.example.org
        websiteId: 00000000-0000-0000-0000-000000000000
      vtapi:
        apikey: REDACTED

  - origin: https://example.org
    options:
      customRedirect: /dashboard
      disable:
        homepage: false
        limits: true
        signup: false
        twoFactor: true

smtp:
  enabled: true
  from: no-reply@example.org
  host: smtp.example.org
  port: 465
  secure: true
  user: no-reply@example.org
  pass: REDACTED

Top-level fields

appname

appname: Snapp
  • Display name of the application
  • Used in UI, authentication flows, and email templates
  • Optional
  • Defaults to Snapp

Admin bootstrap

admin:
  - email: admin@example.org
    username: admin

Admin entries are reconciled on startup.

Behavior:

  • On startup, Snapp ensures that each configured admin exists
  • If an admin user is deleted from the UI, it is recreated on next startup
  • Passwords are generated once and printed to logs
  • Passwords are never regenerated automatically
  • Removing this section does not remove existing admins

Fields:

  • email Required, validated email address

  • username Required, minimum length enforced


Hosts

The hosts array defines all allowed public origins and their runtime behavior.

Each entry represents a logical tenant.

hosts:
  - origin: https://example.org

origin

  • Fully qualified origin (protocol required)

  • Used for:

    • CORS validation
    • Redirect validation
    • Public link resolution
    • Authentication base URL
  • A slugified version of the origin is used as the organization ID in the database


options

Per-host behavioral configuration.

customRedirect

customRedirect: /dashboard
  • Default redirect path when the homepage is disabled
  • Applied after authentication
  • Defaults to /dashboard

disable

Feature-level switches.

disable:
  homepage: false
  limits: true
  lowerCaseFallback: true
  signup: false
  twoFactor: true
  • homepage Disable the public landing page

  • limits Disable rate limiting and usage limits entirely

  • lowerCaseFallback Disable automatic lowercase shortcode fallback

  • signup Disable public user registration

  • twoFactor Disable 2FA enforcement and setup

These flags directly influence authentication, routing, and rate-limiting behavior.


limits

limits:
  maxSnappPerUser: 0
  requestsPerDay: 100
  requestsPerMinute: 14400
  • maxSnappPerUser

    • -1 or negative values = unlimited
  • requestsPerDay

    • Per user, per host
  • requestsPerMinute

    • Burst protection

Limits are enforced only if disable.limits is false.

Internally, limits influence both API key throttling and authenticated requests.


Third-party integrations

Umami analytics

thirdparty:
  umami:
    url: https://metrics.example.org
    websiteId: 00000000-0000-0000-0000-000000000000
  • Enables server-side analytics

  • Used for:

    • Visit logging
    • Aggregated metrics
  • Optional

  • Disabled if omitted


VirusTotal API

thirdparty:
  vtapi:
    apikey: REDACTED
  • Enables URL reputation checks

  • Used during:

    • Link creation
    • Security audits
  • Optional

  • Strongly recommended for public instances


SMTP configuration

SMTP is used for authentication-related emails.

smtp:
  enabled: true
  from: no-reply@example.org
  host: smtp.example.org
  port: 465
  secure: true
  user: no-reply@example.org
  pass: REDACTED

Fields:

  • enabled When false, emails are rendered to logs

  • from Sender address

  • host SMTP server hostname

  • port Usually 465 (implicit TLS) or 587

  • securetrue for implicit TLS

  • user

  • pass

SMTP credentials are never stored elsewhere.


Runtime behavior

  • Configuration is reloaded on file change
  • Invalid updates are rejected
  • The last valid configuration remains active
  • Authentication clients are refreshed per host when relevant settings change
  • No restart required

Notes

  • settings.yaml is stateful

  • Back it up together with:

    • PostgreSQL volume
    • Uploaded assets (avatars, logos)
  • Secrets are stored in plain text

    • Protect the file accordingly
  • Beta versions may introduce new fields or defaults

Prev
Installation
Next
Styling