Skip to main content
SQLPage uses a component-based rendering system that transforms SQL query results into interactive user interfaces. Each component is a reusable UI element configured through SQL SELECT statements.

Component Basics

Components are the building blocks of SQLPage pages. You select a component and configure it using SQL:
-- Select a component
SELECT 'card' as component,
       'My Dashboard' as title;

-- Add items to the component
SELECT 
    'Total Users' as title,
    user_count as value,
    'users' as icon
FROM statistics;
The column named component tells SQLPage which UI component to render. All other columns configure that component’s appearance and behavior.

How Component Rendering Works

Two-Row Pattern

Most components follow a two-row pattern:
1

Component Row

First row with component column defines which component to use and sets top-level parameters:
SELECT 'list' as component,
       'Users' as title,
       'No users found' as empty_title;
Top-level parameters control the component’s overall appearance.
2

Item Rows

Subsequent rows without component column become items within that component:
SELECT 
    name as title,
    email as description,
    avatar_url as image
FROM users;
Each row creates one item in the list.

Complete Example

-- Component initialization
SELECT 'card' as component,
       3 as columns;

-- Items
SELECT 
    'Product Sales' as title,
    '$' || sales_total as value,
    'green' as color
FROM metrics WHERE metric = 'sales';

SELECT 
    'Active Users' as title,
    user_count as value,
    'blue' as color
FROM metrics WHERE metric = 'users';

SELECT 
    'Page Views' as title,
    views as value,
    'orange' as color
FROM metrics WHERE metric = 'views';

Component Lifecycle

Components follow a three-phase lifecycle:

Template Structure

Each component is defined by a Handlebars template split into three parts:
{{! before_list: Renders once when component starts }}
<div class="row row-cards">
  <h2>{{title}}</h2>

{{#each_row}}
  {{! list_content: Renders for each data row }}
  <div class="col-md-{{../columns}}">
    <div class="card card-{{color}}">
      <div class="card-body">
        <h3>{{title}}</h3>
        <div class="display-6">{{value}}</div>
      </div>
    </div>
  </div>
{{/each_row}}

{{! after_list: Renders once when component ends }}
</div>
PhaseWhen it runsAccess toPurpose
before_listComponent initializationTop-level parametersRender headers, containers
list_contentFor each item rowRow data + top-level paramsRender individual items
after_listComponent closureTop-level parametersRender footers, close containers

Component Types

SQLPage provides different component categories:

Header Components

These must be used before any other component (before sending HTTP response):

redirect

SELECT 'redirect' as component,
       '/login' as link;
Performs HTTP redirects

http_header

SELECT 'http_header' as component,
       'Cache-Control' as header,
       'max-age=3600' as value;
Sets custom HTTP headers

cookie

SELECT 'cookie' as component,
       'session_id' as name,
       'abc123' as value;
Manages browser cookies

authentication

SELECT 'authentication' as component,
       $password_hash as password_hash,
       $password as password;
Protects pages with passwords
Header components cannot be used after response streaming has started. Always place them at the top of your SQL file.

Layout Components

SELECT 'shell' as component,
       'My App' as title,
       'home' as icon,
       'A SQL-powered application' as description;
Wraps the entire page with:
  • HTML <head> section
  • Navigation menu
  • Footer
  • CSS/JS includes

Display Components

SELECT 'table' as component,
       TRUE as sort,
       TRUE as search;

SELECT 
    name as "Name",
    email as "Email",
    created_at as "Joined"
FROM users
ORDER BY created_at DESC;
Features:
  • Sortable columns
  • Search filtering
  • Pagination
  • Responsive design
SELECT 'list' as component,
       'Tasks' as title;

SELECT 
    task_name as title,
    description,
    'edit.sql?id=' || id as link
FROM tasks;
Displays items with:
  • Title and description
  • Icons or images
  • Action links
SELECT 'card' as component,
       3 as columns;

SELECT 
    title,
    description,
    image_url as top_image,
    link
FROM products;
Responsive grid layout:
  • 1-6 columns
  • Images and text
  • Clickable cards
SELECT 'chart' as component,
       'Revenue Trends' as title,
       'bar' as type;

SELECT 
    month as label,
    revenue as value,
    'Revenue' as series
FROM monthly_stats;
Chart types:
  • bar, line, area
  • pie, donut
  • scatter

Form Components

SELECT 'form' as component,
       'user_update' as id,
       'Update User' as title,
       'Save Changes' as validate;

-- Text input
SELECT 'text' as type,
       'username' as name,
       'Username' as label,
       $current_username as value,
       TRUE as required;

-- Email input
SELECT 'email' as type,
       'email' as name,
       'Email Address' as label;

-- Select dropdown
SELECT 'select' as type,
       'role' as name,
       'User Role' as label;
       
SELECT 
    role_id as value,
    role_name as label
FROM roles;
Accessing form data:
-- POST parameters use :name syntax
UPDATE users
SET 
    username = :username,
    email = :email,
    role = :role
WHERE id = $user_id;
See SQL Parameters for details on parameter types.

Multiple Components in One Page

Switch between components by selecting a new component:
-- Component 1: Hero
SELECT 'hero' as component,
       'Dashboard' as title;

-- Component 2: Cards
SELECT 'card' as component,
       3 as columns;
SELECT 'Sales' as title, sales as value FROM metrics;

-- Component 3: Table
SELECT 'table' as component,
       'Recent Orders' as title;
SELECT * FROM orders LIMIT 10;

-- Component 4: Chart
SELECT 'chart' as component,
       'Trends' as title,
       'line' as type;
SELECT date as label, revenue as value FROM daily_stats;
Each new SELECT ... as component statement closes the previous component and starts a new one.

Query-to-Component Mapping

SQLPage maps SQL columns to component properties:
SELECT 'card' as component;

SELECT 
    product_name as title,
    description,
    price as value,
    category as footer,
    image_url as top_image,
    '/product?id=' || product_id as link
FROM products
WHERE featured = TRUE;

Component Properties

Each component has its own set of properties:

Top-Level vs Row-Level Properties

SELECT 'table' as component,
       'Users' as title,           -- Top-level
       TRUE as sort,               -- Top-level
       TRUE as search,             -- Top-level
       10 as page_size;            -- Top-level
  • Top-level: Configured in the component initialization row
  • Row-level: Different for each data row

Special Components

json Component - API Responses

api/users.sql
SELECT 'json' as component,
       'array' as type;

SELECT 
    user_id as id,
    username,
    email,
    created_at
FROM users;
Response:
[
  {"id": 1, "username": "alice", "email": "alice@example.com", "created_at": "2024-01-15"},
  {"id": 2, "username": "bob", "email": "bob@example.com", "created_at": "2024-01-16"}
]
TypeFormatUse Case
array[{...}, {...}]REST API lists
jsonlines{...}\n{...}Streaming data
sseServer-Sent EventsReal-time updates

csv Component - Data Export

export/users.sql
SELECT 'csv' as component,
       'users' as filename,
       ';' as separator;

SELECT 
    name,
    email,
    signup_date
FROM users;
Downloads as users.csv:
name;email;signup_date
Alice;alice@example.com;2024-01-15
Bob;bob@example.com;2024-01-16

debug Component - Development Tool

SELECT 'debug' as component;

SELECT 
    $user_id as user_id,
    $filter as filter,
    :search_term as search_term;
Displays raw parameter values for debugging.

Custom Components

Create your own components with Handlebars templates:
1

Create Template File

Create sqlpage/templates/my_component.handlebars:
<div class="my-component">
  <h2>{{title}}</h2>
  <div class="items">
  {{#each_row}}
    <div class="item item-{{color}}">
      <strong>{{name}}</strong>: {{value}}
    </div>
  {{/each_row}}
  </div>
</div>
2

Use in SQL

SELECT 'my_component' as component,
       'Custom Display' as title;

SELECT 
    item_name as name,
    item_value as value,
    'blue' as color
FROM my_data;
Custom components let you extend SQLPage with your own UI patterns and branding.

Best Practices

  • Use table for data that needs sorting/filtering
  • Use list for simple item displays with actions
  • Use card for visual, grid-based layouts
  • Use chart for metrics and trends
  • Limit rows with SQL LIMIT clause
  • Use pagination for large datasets
  • Avoid selecting unnecessary columns
  • Index database columns used in WHERE clauses
  • Provide descriptive title attributes
  • Use semantic component choices
  • Include alt text for images
  • Test with keyboard navigation
  • Keep components simple and focused
  • Use comments to explain complex queries
  • Extract common patterns into reusable SQL files
  • Document custom component templates

Next Steps

Component Reference

Browse all available components

SQL Parameters

Master parameter handling

Custom Components

Build your own components

Examples

See components in action

Build docs developers (and LLMs) love