Custom Theme Creation
This guide walks you through creating a custom theme from scratch -
1. Plan the theme & folder structure
Create a directory under web/themes/custom/yourtheme (or themes/custom/yourtheme depending on your project layout). Minimal structure:
yourtheme/
yourtheme.info.yml
yourtheme.libraries.yml
templates/
html.html.twig
page.html.twig
node--article.html.twig
css/
base.css
js/
theme.js
src/
yourtheme.theme2. Define the theme: yourtheme.info.yml
This is the metadata Drupal reads to register the theme. Minimal example:
Attach in .info.yml (see above) for global loading, or attach in templates/preprocess for conditional loading.
Why libraries? Drupal aggregates and controls asset loading (cache-busting, aggregation, dependency ordering). Avoid embedding <link> or <script> tags directly in Twig. (Best practice.)
In Drupal’s libraries.yml, the empty curly braces {} simply mean: Use default settings - no extra attributes or options. No attributes, no weight, no media query, no preprocessing change.
If you want to add attributes:
css:
theme:
css/style.css:
media: screen
weight: 10
js:
https://example.com/script.js:
attributes:
defer: true4. Base HTML and page templates (Twig)
Twig is the template engine. You’ll usually override:
html.html.twig— top-level HTML (head, html lang, attributes,page_top/page_bottomplaceholders).page.html.twig— main page layout; outputs{{ page.header }},{{ page.content }}, etc.node.html.twig,block.html.twig, etc. — override specific entities.
Example page.html.twig snippet showing regions: