TH SeedWebs

Themes and templates

What a SeedWebs theme holds, what each kind of theme part is, how a template is chosen for each URL, and how to change colours, fonts and Tailwind.

Last updated 2026-10-29

Everything about how your public site looks comes from a theme, stored inside your own site. A theme holds the HTML of the header and footer, the global CSS and JavaScript, and the smaller pieces — theme parts — that decide how a post, a product or a category page is rendered.

This guide covers what a theme holds, where to edit it, and the order in which SeedWebs picks a template for a URL.

Themes are managed at Settings → Themes (/admin/settings/themes).

What one theme holds

Each theme carries these values of its own. The first five are edited on the General tab of the theme editor; Thumbnail is in the right sidebar, visible from every tab.

FieldLabel on screenWhat it does
header_htmlHeaderThe header HTML shown on every page
footer_htmlFooterThe footer HTML shown on every page
global_cssGlobal StylesEverything placed in <head> — Google Fonts <link> tags, the Tailwind script, <style> blocks
global_jsGlobal JavaScriptA script placed at the end of <body> on every page. Write the code only, no <script> tag
body_classBody classTailwind classes applied to the <body> tag, such as background colour and font
thumbnailThumbnailThe cover image on the theme card in the list. .webp only, up to 2 MB

Header, Footer, Global Styles, Global JavaScript and Body class each hold up to about 1 MB. Over that, the save is refused and you are told which field is too big.

The tabs in the theme editor

Opening a theme shows pill tabs at the top.

TabURLContents
General/admin/settings/themes/{id}Header, Footer, Global Styles, Global JavaScript, Body class
Nav/admin/settings/themes/{id}/navThe elements that build the menu (slugs starting nav-)
Elements/admin/settings/themes/{id}/elementsReusable elements, such as a post card or product card
Templates/admin/settings/themes/{id}/templatesThe template for each kind of page
Emails/admin/settings/themes/{id}/emailsEmail templates. Shown while Newsletters, Forms, Donations or the Store is on under Settings → General → Features

Every tab shares the same right sidebar: the status box (Active / Inactive), the theme name, its slug, the save button, the Thumbnail box, and an Options box holding a pop-out tag reference and the Export Theme button.

Expanding a theme part’s card gives three sub-tabs:

  • Content — edit the text and images in the code without touching HTML
  • Style — edit each element’s Tailwind classes
  • HTML — edit the code directly, with a format button

Collapsed, a card shows a small rendered preview. Click the preview to expand, and the pencil icon in the card header to change that part’s name and slug.

Kinds of theme part

In the database a theme part’s type is one of header, footer, element, template or email.

In practice, in the current version:

  • element — a piece called from elsewhere with {{> slug}}, such as post-card inside a post-list loop. Elements whose slug starts nav- are split out into the Nav tab; the rest live under Elements.
  • template — the shell for one whole page, such as post-list for the post listing.
  • email — the body of a system email, such as the subscription confirmation.
  • header and footer — still accepted by the API, but the header and footer actually rendered come from header_html and footer_html on the theme itself, not from parts. That is why there are no Headers or Footers tabs, and why importing a theme from a ZIP skips parts of those two types.

A part’s slug has to be unique within one theme and one type — so an element called post-detail and a template called post-detail can coexist.

The Elements and Templates lists hide parts belonging to content types you have switched off under Settings → General → Features, going by the slug prefix (post-, event-, product-, book-, staff-, doc-, slider-, member-, donation-). Parts not tied to a content type — page, category, tag, search-results, not-found — are always shown.

That filter does not cover slugs starting tour-, so tour templates always remain in the list. Tours are in no plan’s permissions; the SeedWebs team has to turn on the experimental flag for your site before they do anything. Until then, editing a tour template changes nothing, because no page calls it.

How a template is chosen

When somebody opens a URL, SeedWebs picks a template through three nested fallbacks.

Layer 1 — the active theme, then the default theme

Parts are taken from the Active theme first, and the gaps filled from the theme whose slug is default, matching on the pair of type + slug. That is why a brand-new theme with no parts at all still renders a complete site: it borrows every part from the default theme. Create a part with the same name in your own theme and yours immediately wins.

Layer 2 — a specific slug, then the general one

A category page looks for a template named for that category first, and falls back to the general one. The category news looks for category-news, and failing that uses category. This is how you make one category look different from the others without touching the shared template.

Layer 3 — type template, then type element

Once the slug is settled, SeedWebs looks for a part of type template first, and failing that a part of type element with the same slug.

The order per URL

{slug} below is the slug of the category, brand or page template being viewed.

PageSearch order
A Page written in Article modepage-{page template slug} → page
/postspost-list
/posts/:slugpost-detail-page → post-detail
/category/:slug (or /category/:parent/:slug, nested)category-{slug} → category
/tag/:slugtag
/eventsevent-list
/events/:slugevent-detail-page → event-detail
/productsproduct-list
/products/:slugproduct-detail-page → product-detail
/product-categories/:slugproduct-category-{slug} → product-category
/product-brands/:slugproduct-brand-{slug} → product-brand
/tourstour-list
/tours/:slugtour-detail-page → tour-detail
/tour-category/:slugtour-category-{slug} → tour-category
/tours/bookings/:booking_numbertour-thankyou
/staffsstaff-list
/staffs/:slugstaff-detail-page → staff-detail
/staff-categories/:slugstaff-category-{slug} → staff-category → staff-list
/authorsauthor-list
/authors/:slugauthor-detail-page → author-detail
/booksbook-list
/books/:slugbook-detail-page → book-detail
/book-categories/:slugbook-category-{slug} → book-category
/docs/:slugdoc-detail-page → doc-detail
/searchsearch-results
/cartcart — only while the store is on (Store settings → Checkout enabled + a payment gateway); otherwise 404
/checkoutcheckout — same condition
/orders/:order_numberorder-received
A page that does not exist (404)not-found

A page of your own slugged cart, checkout or orders is served instead of the store page — pages come first, as everywhere else. A WooCommerce import brings such pages along; set them to draft to let the store pages through.

If nothing in the order matches, that content page answers 404 — except Pages, which still render their content plainly with no template. For not-found, a missing template falls back to a built-in page. The not-found template supports {{site_name}} and {{> partial}} (so a shared sidebar or footer block still appears); item tags are not rendered there, because a 404 has no item.

The tags used inside templates are documented in Template tags.

What the default theme ships with

Every new site gets a theme called Default (slug default), with this factory set of parts.

Templates

page · post-list · post-detail-page · category · tag · event-list · event-detail-page · product-list · product-detail-page · product-category · product-brand · tour-list · tour-detail-page · tour-category · tour-thankyou · staff-list · staff-detail-page · staff-category · author-list · author-detail-page · book-list · book-detail-page · book-category · doc-detail-page · search-results · not-found · order-received · cart · checkout

Elements

post-card · event-card · product-card · tour-card · staff-card · book-card · author-card · post-detail · event-detail · language-switcher

Elements on the Nav tab

nav-item · nav-submenu · nav-mega-header · nav-mega-column · nav-mobile-item · nav-mobile-submenu · nav-mobile-mega · nav-mobile-mega-column · nav-mobile-drawer

Emails

email-confirm · email-welcome · email-newsletter · email-unsubscribe · subscribe-form

The Templates tab starts with Page Templates, listing your page templates (Default and Landing come as standard). One never customised shows a dashed box saying it uses the default layout, with Customize, which creates page-default or page-landing to edit: Default starts as a copy of page, Landing as an empty shell with no header or footer, since a landing page controls the whole page.

Putting {{header}} and {{footer}} in a page template inserts the theme’s header and footer at exactly that point, and SeedWebs then does not insert them again. The exception is a page using the Landing page template, where both tags render as nothing.

The default theme: resettable, not deletable

The default theme differs from the others in three ways.

  1. It cannot be deleted. The bin icon in the corner of the status box becomes a reset button instead, and a delete through the API is refused.
  2. It cannot be deactivated. Pressing Inactive while the default theme is the Active one warns you to activate another theme first.
  3. Its factory parts cannot be deleted. Parts that shipped with the platform are protected, with a message saying they are built in and to use Reset instead. Parts you added to this theme yourself delete normally.

Reset to default (the circular-arrow icon right of the status box) renames the theme Default, restores Header, Footer, Global Styles and Body class to factory values, empties Global JavaScript, then deletes every theme part in this theme and re-inserts the factory set — your customisations and your own parts are gone. To experiment safely, work in a new theme.

Any theme other than default can be deleted, and deleting the Active theme switches back to the default theme automatically. Media library images the theme referenced are not deleted with it.

The theme library

Settings → Themes shows a Theme library strip with themes that ship with SeedWebs. Clicking Install creates an ordinary theme on your site — not active until you activate it, and editable, exportable and deletable like any theme you made. A theme in the library overrides only the parts it cares about; everything else falls back to Default, so it keeps working as new content types arrive.

ThemeWhat it changesNotes
ShopHeader with search and cart icon, footer with menu and subscribe form, image-first product cards with an Add-to-cart button, gallery-first product page, product category/brand/tag archives with sort links, styled cart, checkout, order and search pages, 404, pageBrowse-only until Store → Settings → Enable Checkout and a payment method are set — the same theme then sells. Install also creates a draft page Shop home (hero, new arrivals, best sellers) for you to edit and set as the homepage. Takes its accent from Settings → General → Primary colour

Installing a second time is refused while a theme with that slug exists — delete yours first if you want the factory version back.

Creating a theme, and importing from a ZIP

Add Theme

Settings → Themes → Add Theme (/admin/settings/themes/new). Enter a name and press Create Theme.

The Import HTML field on that page is optional. Paste a single page of HTML and SeedWebs tries to split it up: <script> tags, font and CSS <link> tags and <style> blocks from <head> become Global Styles; a <nav> pinned to the top of the viewport, or a <header>, becomes the header; <footer> becomes the footer; and the contents of <main> or <body> become a home page (slug home), with a checkbox for whether to replace the existing one.

A theme created here is activated immediately and has no theme parts of its own, so it borrows all of them from the default theme.

The Import HTML button at the right of the tab bar in the theme editor does the same thing for a theme that already exists.

Upload Theme (ZIP)

The Upload Theme button on the theme list takes a .zip. The structure it reads is:

theme.json          required — name, slug, header_html, footer_html, global_css, global_js
header.html         optional — overrides the value in theme.json
footer.html         optional
parts/element-post-card.html    named {type}-{slug}.html
parts/element-post-card.json    metadata — name, slug, type, sort_order

Limits: the ZIP itself up to 2 MB, at most 100 files inside, and up to 5 MB of extracted content. Without theme.json the upload is refused.

If the slug collides with an existing theme, a number is appended — mytheme-2. An imported theme is not activated; press Activate yourself.

Export Theme

In the Options box of the right sidebar in the theme editor. It downloads {slug}.zip.

In the current version that file contains a theme.json with the name, slug, Global Styles and Global JavaScript. The header, the footer and the theme parts in parts/ are not yet included, so do not use this file as a backup. To back up the whole site, use Tools → Backup (/admin/tools/backup).

Tailwind: CDN or Optimize

Public pages are styled with the Tailwind classes written into your theme’s HTML, so the browser has to get the CSS for those classes from somewhere. Two buttons at the bottom of the HTML tab of the Global Styles editor handle this.

Use CDN adds Tailwind v4’s browser build to Global Styles with a <style type="text/tailwindcss"> @theme starter of two colours (foreground, background). A Tailwind v3 script is removed; if v4 is already there you are told so and nothing is duplicated. Classes compile in the visitor’s browser — handy while designing, but every visitor loads an extra external file.

Optimize scans all of this theme’s HTML — header, footer, every theme part, page content written as HTML, and the Body class — compiles only the classes actually used into a <style>/* Tailwind CSS (built) */…</style> block, puts it back into Global Styles, removes the CDN script, and saves immediately. Pages load faster and depend on no external file, which is what you want in production.

The catch with Optimize is that it compiles what exists at the moment you press it. Every time you add a new Tailwind class to a theme part or a page, press Optimize again, or that class has no CSS behind it.

Changing colours and fonts (Global Styles)

The Global Styles editor reads the colours and fonts out of your code for you. Collapsed, it shows a row of colour swatches and an “Aa” font sample. Expand it for three tabs.

Colors lists every declared colour. Click a swatch to open a colour picker; the value is written straight back into the code. Add colour creates a new one (names may use English letters, digits, hyphens and underscores), and the bin icon that appears on hover removes it. A colour’s name becomes a usable class — a colour called accent gives you bg-accent and text-accent.

The default theme comes with five: foreground, background, card, muted, primary.

Fonts lists the declared fonts with a Thai sample sentence. Change opens a Google Fonts search (hover a name to preview it before choosing). Add font adds another, starting with a “key” — the key becomes the class, so a key of heading gives you font-heading.

Whenever you change, add or remove a font, SeedWebs rewrites the whole Google Fonts <link> tag itself, requesting weights 400, 500, 600 and 700 and the latin and thai subsets. There is no need to edit that link by hand.

The font picker includes the Thai fonts people use most — Noto Sans Thai, Sarabun, Kanit, Prompt, Mitr, Niramit, IBM Plex Sans Thai, Bai Jamjuree, Pridi, Itim — and you can search Google Fonts for anything else.

Uploading your own font

A font not on Google Fonts (a brand font, or a foundry’s Thai display font) can be uploaded: at the bottom of the Fonts tab, under Uploaded fonts, press Upload font and pick the files (.woff2, .woff, .ttf or .otf; .woff2 is smallest and fastest), one per weight and style (Regular 400, Bold 700, Italic…). SeedWebs guesses family, weight and style from each file name (SaoChingcha-Bold.woff2 → Sao Chingcha, 700, normal); correct any guess, then press Save font.

The files go into your media library, and SeedWebs writes the @font-face rules (with font-display: swap) into Global Styles for you. The family then appears at the top of the font picker under Uploaded — choose it with Change for font-body, font-heading or any other key, and the fallbacks you already had (for example sans-serif) are kept. An uploaded font is never requested from Google Fonts. When it is the font-body font, its regular file is preloaded so the text appears in it sooner.

Remember to press Save on the theme afterwards. A family that a font key still uses cannot be removed — switch that key to another font first. Uploaded fonts travel with the theme when you export or import it, and with a theme created from it; the files themselves stay in this site’s media library, so do not delete them there.

An AI app connected over MCP can install a font the same way (set_theme_font then set_theme_font_role, or /api/themes/{id}/fonts over REST) instead of editing Global Styles by hand.

HTML is the raw editor for the whole of Global Styles, for writing your own CSS or editing the @theme block directly. The Use CDN and Optimize buttons are on this tab.

The default theme also ships a set of .prose CSS in Global Styles, which styles headings, paragraphs, lists and tables inside post content. Edit it as you like.

Who can edit themes

Themes fall under the settings.themes permission, held by two roles.

RoleCan open ThemesCan edit / create / delete themes and parts
super_adminYesYes
adminYesYes
editorNoNo
writerNoNo

Heavier operations are super_admin only: wiping the site’s content at Tools → Reset, and restoring from a backup at Tools → Backup (creating a backup goes up to admin). Roles are described in Users and permissions.

The theme system is not limited by plan: every plan edits and creates themes and templates alike. The plan decides which content types the site can enable, which hides the disabled types’ templates and makes their public pages answer 404; the per-site experimental flag covers Events, Docs, Books, Staffs, Members, Newsletters, Tours and Donations. See Plans and billing.

Common misunderstandings

Edited the theme, but the site has not changed. First check that the theme you edited is the Active one: the status box in the right sidebar must say Active, and the card in the theme list shows a solid badge. The other common cause is adding new Tailwind classes after having pressed Optimize — press Optimize again.

Created a new theme and the site looks the same. That is correct. A new theme has no parts of its own, so it borrows all of them from the default theme until you create a part with the same name to override it.

Want one category to look different from the others. Do not edit the category template. Create a new template called category-{that category's slug} and SeedWebs will use it for that category only.

Reset cannot be undone. After one confirmation it overwrites the default theme with factory values and deletes all its parts. The only way back is Tools → Backup, which rolls the whole site (not just the theme) back to a snapshot — and only super_admin can restore.