A reusable, production-ready Hugo static-site template for precision-manufacturing / industrial B2B companies (casting, CNC machining, fabrication, contract manufacturing, etc.).
It ships with a premium, high-conversion industrial UI, a data-driven GEO/Schema
engine (Organization, ManufacturingBusiness, Service, Industry, Product, Article,
FAQ, Breadcrumb, GEO/Place/GeoCoordinates, WebSite), a landing-page section
engine, multilingual support (EN/DE/JA/FR/ES), reusable archetypes
(service, industry, material), and a robust Request-a-Quote (RFQ)
workflow.
This is a template, not a finished site. All brand-specific content has been removed and replaced with configurable placeholders. Brand your site by editing the four files under
config/branding/(the single source of truth) and the demo pages undercontent/.
- Premium industrial B2B UI — sticky 1200px header, hero sections, alternating content bands, styled specification/comparison tables, FAQ accordion, dark CTA band, fully responsive.
- Section engine — landing pages are composed from a
sections:array in front matter (no layout editing required). - Data-driven schema engine — JSON-LD schema types generated from
data/schema/*.tomlandconfig/branding/schema.toml, localized per language: Organization, ManufacturingBusiness, Service, Industry, Product, Article, FAQ, Breadcrumb, GEO (Place + GeoCoordinates), and WebSite. - Multilingual — EN at root,
/de/ /ja/ /fr/ /es/prefixes. Add or remove languages inconfig/_default/languages.toml. - RFQ, with graceful fallback — a single
params.contact.form_actionsetting controls the quote form. If it is empty, the form is replaced by an email CTA instead of a broken submission. See RFQ form. - SEO checks —
scripts/seo-check.pyandscripts/schema-check.pyvalidate every built page (run in CI before deploy). - GitHub Pages ready —
.github/workflows/hugo.ymlbuilds, validates and deploys on push tomain.
- Hugo 0.163.3 (extended) — the build uses extended features (SCSS pipeline
via
resources).enableGitInfo = truerequires the site to be a git repo (git initif you start fresh). - Python 3.12+ (only for the optional local SEO/schema checks).
# 1. Clone / copy this template into your project
git clone <your-repo> my-site
cd my-site
# 2. Initialise git (required for enableGitInfo)
git init -q && git add -A && git commit -m "init"
# 3. Build (or run `hugo server -D` to preview)
hugo --gc --minify
# 4. (optional) run the quality gates locally
python scripts/seo-check.py ./public
python scripts/schema-check.py ./publicPreview with hugo server and open http://localhost:1313/.
Brand identity lives in four separate source files under config/branding/
(this is your single source of truth):
| File | Purpose |
|---|---|
company.toml |
Company name, tagline, logo mark / wordmark ([params.company]) |
contact.toml |
Email, phone, address, RFQ form_action ([params.contact]) |
seo.toml |
Site-wide default description + keywords ([params.seo]) |
schema.toml |
Brand identity for structured data: legalName, url, logo, images, address*, latitude/longitude, sameAs, certifications ([params.schema]) |
config/_default/params.toml is the only config file Hugo reads for custom
[params.*] values, and Hugo will not auto-load arbitrary filenames such as
seo.toml or company.toml. So scripts/sync-branding.py merges the four
config/branding/*.toml files into the [params] namespace of
config/_default/params.toml (rewriting [params.company] → [company], etc.).
The sync runs automatically:
- in the GitHub Actions workflow (
.github/workflows/hugo.yml) beforehugo, - in
scripts/init-site.shafter you edit branding, and - the merged result is committed, so a fresh clone builds correctly with no extra step.
Rule: edit
config/branding/*.tomlonly. Never hand-edit the generated brand block insideconfig/_default/params.toml— it is regenerated by the sync script and fenced withBRANDING SYNC START / ENDcomment markers.
# config/branding/company.toml
[params.company]
name = "Acme Precision Castings"
tagline = "Precision Manufacturing & Engineering"
[params.company.branding]
logo = "" # empty = text wordmark (first 2 letters of name)
logo_mark = "AP" # 1-3 letter monogram shown in the header logo markAlso set the real domain in config/_default/hugo.toml → baseURL.
Menus are fully editable through language-specific files
(config/_default/menus.en.toml, menus.de.toml, …). The default set is:
Home, Services, Materials, Industries, Processes, Resources, Contact. No menus
are hardcoded in layouts. To add/remove items, edit these TOML files only.
The RFQ form (layouts/partials/sections/rfq.html and the rfq_form shortcode)
reads a single setting: params.contact.form_action.
- If
form_actionis set (e.g. a Formspree/HubSpot URL), a working form is rendered that POSTs to that endpoint. - If
form_actionis empty, the template does not render a broken form. Instead it shows an email CTA (mailto tocontact.email) so visitors can still request a quote. This prevents dead/broken submissions on a fresh clone.
Requirement: never ship a default third-party form ID. The template ships with
form_action = ""and the email fallback. Set your own endpoint inparams.toml.
Demo pages are provided so the site builds out-of-the-box. Replace them with your own; the folder structure maps to the navigation:
content/
_index.md # Homepage (layout: landing, section engine)
services/ # 5 service pages (layout: single)
precision-casting/
cnc-machining/
sheet-metal-fabrication/
surface-treatment/
assembly-services/
materials/example-material/ # Material page (archetype-driven)
industries/ # 5 industry pages (layout: single)
pump-valve/
marine/
automotive/
food-machinery/
chemical-processing/
processes/example-process/ # Process page
resources/example-resource/ # Resource / guide (uses capability_table)
contact/ # Contact page (RFQ)
services/_index.md # Section listing
materials/_index.md
industries/_index.md
processes/_index.md
resources/_index.md
hugo new services/my-part/index.md # uses archetypes/service.md
hugo new industries/my-vertical/index.md # uses archetypes/industry.md
hugo new materials/my-alloy/index.md # uses archetypes/material.mdEach archetype ships realistic front matter (layout: "single", categories,
service/materials/applications/industries linking, internal_linking,
seo, and a schema.faq block) plus a body scaffold with capability_table,
process_flow, and rfq_form shortcodes. Edit the values and rebuild — the page
appears automatically in the section listing and menu.
Shortcodes:
{{< image src title >}},{{< process_flow steps >}},{{< capability_table ... >}}…{{< /capability_table >}}(must be closed),{{< faq_accordion >}},{{< rfq_form >}},{{< case_study >}},{{< material_selector >}}.
- Languages are defined in
config/_default/languages.toml(EN is the default content language at the site root). - Each language has its own menu file (
menus.<lang>.toml) and its own content tree (content/<lang>/…) created viahugo new/ translation folders. translationKeylinks equivalent pages across languages (omit it on example pages; add it when you create real translated pairs).- Schema strings are localized in
data/schema/*.tomlunder[en.<id>],[de.<id>],[ja.<id>],[fr.<id>],[es.<id>]maps.
To add a language: add a block to languages.toml, create
menus.<lang>.toml, and add a <lang>.<id> map to every relevant
data/schema/*.toml.
JSON-LD is generated from data/schema/*.toml and injected by
layouts/partials/schema/render.html. All brand fields fall back to
params.toml (so the generic template still produces valid Organization schema).
| File | Schema type(s) emitted |
|---|---|
organization.toml |
Organization (site-wide, in every page head) |
manufacturing.toml |
ManufacturingBusiness (knowsAbout / makesOffer / address) |
services.toml |
Service (matched by url_path) |
industries.toml |
Industry (custom @type, matched by url_path, provider → Organization) |
products.toml |
Product (matched by url_path) |
locations.toml |
GEO — Place + GeoCoordinates (linked from Organization) |
certifications.toml |
certifications (ISO 9001 / IATF 16949) on Organization |
In addition, every page that defines a schema.faq front-matter block emits an
FAQ (FAQPage) schema, and Breadcrumb (BreadcrumbList) is emitted for
every interior page. The full set requested for V3 — ManufacturingBusiness,
Service, Industry, GEO entity, FAQ, Breadcrumb — is therefore generated
automatically.
Match a page to a schema entry by setting url_path in the schema file equal to
the page’s .Dir (e.g. url_path = "/services/precision-casting/").
python scripts/seo-check.py ./public # every page needs a meta description
python scripts/schema-check.py ./public # JSON-LD well-formed & linkedBoth scripts run automatically in the GitHub Actions deploy and will fail the build if any page is missing a meta description or a schema block is malformed.
- Push the template to a GitHub repo (e.g.
industrial-manufacturer-hugo-template-2.1). - In Settings → Pages → Build and deployment, set Source = GitHub Actions.
- Push to
main..github/workflows/hugo.ymlwill build, run the SEO/schema checks, and deploy to GitHub Pages.
The workflow uses Hugo 0.163.3 (extended) and uploads ./public as the Pages
artifact. To deploy elsewhere (Netlify, Cloudflare Pages, S3), just run
hugo --gc --minify and serve the public/ folder.
config/_default/ # hugo.toml, languages.toml, params.toml, menus.*.toml
content/ # example pages (replace with your content)
data/schema/ # schema engine data (localized)
layouts/
_default/ # baseof, landing, single, list, markup render hooks
partials/ # head, header, footer, cta-band, sections/*, schema/*
shortcodes/ # image, rfq_form, faq_accordion, process_flow, capability_table
assets/css/main.css # design system
static/ # favicon, robots.txt, etc.
scripts/ # seo-check.py, schema-check.py
.github/workflows/ # hugo.yml (build + deploy)
See LICENSE.