select 'http_header' as component, 'public, max-age=300, stale-while-revalidate=3600, stale-if-error=86400' as "Cache-Control"; select 'dynamic' as component, properties FROM example WHERE component = 'shell' LIMIT 1; select 'hero' as component, 'Custom URLs' as title, 'SQLPage lets you customize responses to URLs that don''t match any file, using `404.sql`.' as description_md, 'not_found.jpg' as image; select 'text' as component, ' # Handling custom URLs By default, SQLPage serves the file that matches the URL requested by the client. If your users enter `https://example.com/about`, SQLPage will serve the file `about/index.sql` in your project. If you create a file named `about.sql`, SQLPage will serve it when the user requests either `https://example.com/about.sql` or `https://example.com/about` (since v0.33, the `.sql` suffix is optional). But what if you want to handle URLs that don''t match any file in your project ? For example, what if you have a blog, and you want nice urls like `example.com/blog/my-trip-to-rome`, but you don''t want to create a file for each blog post ? By default, SQLPage would return a sad 404 error if you don''t have a file named `blog/my-trip-to-rome/index.sql` in your project''s root directory. But you can customize this behavior by creating a file named `404.sql` in your project. ## The 404.sql file When SQLPage doesn''t find a file that matches the URL requested by the client, it will serve the file `404.sql` if it exists. Since v0.28, when SQLPage receives a request for a URL like `https://example.com/a/b/c`, it will look for the file `a/b/c/index.sql` in your project, and if it doesn''t find it, it will then search for, in order: - `/a/b/404.sql` - `/a/404.sql` - `/404.sql` ## Basic routing example So, you have a `blog_posts` table in your database, with columns `name`, and `content`. You want to serve the content of the blog post with id `:id` when the user requests `example.com/blog/:id`. You can do this by creating a `404.sql` file in the `blog` directory of your project: ```sql -- blog/404.sql -- Get the id from the URL set name = substr(sqlpage.path(), 1+length(''/blog/'')); -- Get the blog post from the database select ''text'' as component, content as contents_md from blog_posts where name = $name; ``` Now, when a user requests `example.com/blog/my-trip-to-rome`, SQLPage will serve the content of the blog post with name `my-trip-to-rome` from the `blog_posts` table. ' as contents_md;