Skip to main content
The shell component wraps all page content in a complete HTML page with navigation, styling, and metadata. It controls the overall appearance and structure of your site.

Basic Usage

SELECT 'shell' AS component,
       'My Application' AS title,
       'database' AS icon;

Layout and Appearance

title
text
Page title shown in the browser tab and top bar
navbar_title
text
Different title for the navigation bar (if different from page title)
description
text
Page description for search engines and social media
icon
icon
Icon to display next to the title (from tabler-icons.io)
image
url
Image URL to display next to the title
URL to navigate to when clicking the title/logo
layout
text
default:"boxed"
Page layout: boxed (default), horizontal (full-width menu), vertical (vertical menu), or fluid (no side margins)
theme
text
Set to dark for dark theme
class
text
CSS class to add to the html element
menu_item
text or json
Menu items in the navigation bar. Can be a simple string (links to name.sql) or JSON object for advanced menus with dropdowns.
sidebar
boolean
Display menu on the left side instead of top
sidebar_theme
text
Set to dark to use dark theme for sidebar only
fixed_top_menu
boolean
Fix the navigation bar at the top when scrolling
search_target
url
SQL file to load with a search parameter when users search
search_value
text
Pre-fill the search field with this value (use $search to mirror user input)
search_placeholder
text
default:"Search"
Placeholder text in the search field
search_button
text
default:"Search"
Text on the search button

Styling

css
url
URL of a CSS file to load. Can be specified multiple times.
javascript
url
URL of a JavaScript file to load. Can be specified multiple times.
javascript_module
url
URL of a JavaScript ESM module to load
font
text
Font name from fonts.google.com or path to local WOFF2 file (e.g., /fonts/MyFont.woff2)
font_size
integer
default:"18"
Base font size in pixels

Metadata

favicon
url
URL of the favicon icon for browser tabs and bookmarks
preview_image
url
Image URL for link previews when shared on social media
social_image
url
Alias for preview_image
language
text
Page language code (e.g., en-US, fr-FR) for search engines and screen readers
rtl
boolean
Display page in right-to-left mode for Arabic, Hebrew, Persian, etc.
norobot
boolean
Prevent search engines from indexing this page
rss
url
URL of RSS feed to display in navigation
manifest
url
URL of PWA manifest.json for installable web apps
Markdown text for the page footer. Set to empty string to hide footer. Default: “Built with SQLPage”

Special Features

refresh
integer
Number of seconds before auto-refreshing the page
target
text
Where to open navigation links: _blank, _self, _parent, or _top

Examples

Basic Shell

SELECT 'shell' AS component,
       'My App' AS title,
       'home' AS icon,
       '/' AS link;

Shell with Simple Menu

SELECT 'shell' AS component,
       'My Application' AS title,
       'database' AS icon,
       '/' AS link,
       'about' AS menu_item,
       'contact' AS menu_item,
       'docs' AS menu_item;
This creates links to about.sql, contact.sql, and docs.sql.

Shell with Dropdown Menu

SELECT 'shell' AS component,
       'SQLPage' AS title,
       'database' AS icon,
       '/' AS link,
       json('{"title":"About","submenu":[
           {"link":"/safety.sql","title":"Security","icon":"lock"},
           {"link":"/performance.sql","title":"Performance","icon":"bolt"},
           {"link":"/blog.sql","title":"Articles","icon":"book"}
       ]}') AS menu_item,
       json('{"title":"Community","submenu":[
           {"link":"//github.com/sqlpage/SQLPage","title":"GitHub","icon":"brand-github"},
           {"link":"//github.com/sqlpage/SQLPage/discussions","title":"Discussions","icon":"message"}
       ]}') AS menu_item;

Active Menu Item

SELECT 'shell' AS component,
       'My App' AS title,
       json('{"title":"Home","active":true}') AS menu_item,
       json('{"title":"About"}') AS menu_item;

Shell with Sidebar

SELECT 'shell' AS component,
       'Dashboard' AS title,
       true AS sidebar,
       'dark' AS sidebar_theme,
       'home' AS menu_item,
       'reports' AS menu_item,
       'settings' AS menu_item;
SELECT 'shell' AS component,
       'My Site' AS title,
       'search.sql' AS search_target,
       'Search products...' AS search_placeholder;

Dark Theme

SELECT 'shell' AS component,
       'My App' AS title,
       'dark' AS theme;

Custom Font and Size

SELECT 'shell' AS component,
       'My App' AS title,
       'Poppins' AS font,
       20 AS font_size;

Custom CSS and JavaScript

SELECT 'shell' AS component,
       'My App' AS title,
       '/assets/custom.css' AS css,
       '/assets/custom.js' AS javascript;

Auto-Refresh Page

SELECT 'shell' AS component,
       'Live Dashboard' AS title,
       30 AS refresh; -- Refresh every 30 seconds

Right-to-Left Languages

SELECT 'shell' AS component,
       'تطبيقي' AS title,
       'ar' AS language,
       true AS rtl;

Sharing Shell Across Pages

Static Menu with JSON File

Create shell.json:
{
  "component": "shell",
  "title": "My Application",
  "link": "/",
  "menu_item": [
    {"link": "index.sql", "title": "Home"},
    {"title": "Community", "submenu": [
      {"link": "/blog.sql", "title": "Blog"},
      {"link": "//github.com/user/repo", "title": "GitHub"}
    ]}
  ]
}
Load it in your pages:
SELECT 'dynamic' AS component,
       sqlpage.read_file_as_text('shell.json') AS properties;

Dynamic Menu from Database

Create shell.sql:
SELECT 'shell' AS component,
       'My App' AS title,
       json_group_array(json_object(
           'link', link,
           'title', title,
           'icon', icon
       )) AS menu_item
FROM menu_items
WHERE visible = 1
ORDER BY position;
Load it in your pages:
SELECT 'dynamic' AS component,
       sqlpage.run_sql('shell.sql') AS properties;

Conditional Menu Items

SET role = (
    SELECT role FROM users
    INNER JOIN sessions ON users.id = sessions.user_id
    WHERE sessions.session_id = sqlpage.cookie('session_id')
);

SELECT 'shell' AS component,
       'My Site' AS title,
       -- Admin panel for admins only
       CASE WHEN $role = 'admin'
            THEN '{"link":"admin.sql","title":"Admin Panel"}'
       END AS menu_item,
       -- Profile for authenticated users
       CASE WHEN $role IS NOT NULL
            THEN '{"link":"profile.sql","title":"My Profile"}'
       END AS menu_item,
       -- Login for unauthenticated users
       CASE WHEN $role IS NULL
            THEN 'login'
       END AS menu_item;

Shell-Empty

Use shell-empty to return raw content without SQLPage’s HTML wrapper:
SELECT 'http_header' AS component,
       'application/xml' AS "Content-Type";

SELECT 'shell-empty' AS component,
       '<?xml version="1.0"?><root><data>value</data></root>' AS contents;

Layout Modes

  • boxed: Default centered layout with margins
  • horizontal: Full-width with horizontal top menu
  • vertical: Vertical sidebar menu
  • fluid: Full-width without side margins

Best Practices

  • Define the shell once at the top of each page
  • Use dynamic component to share shell configuration
  • Set description and preview_image for better SEO and social sharing
  • Use fixed_top_menu for long scrolling pages
  • Add norobot to admin or private pages
  • Use sidebar layout for applications with many menu items

Build docs developers (and LLMs) love