File Structure
Skill level: Everyone · Time: 5 minutes
Inside The Theme Folder
You don’t need to understand every folder. Most changes happen in the five places marked in bold below.
Directoryecozen/
Directory.cursor/ rules for the Cursor editor
- …
Directory.github/ instructions for GitHub Copilot
- …
Directory.vscode/ recommended VS Code extensions and settings
- …
Directory.windsurf/ rules for the Windsurf editor
- …
Directorypublic/ files served as they are (favicons, the social image, a sample video, and
_headersand.htaccesshost settings)- …
Directoryscripts/ helper scripts behind the
npm runcommands- …
Directorysrc/
Directory__tests__/ the theme’s unit tests
- …
Directoryassets/
Directoryimages/ your images (logos, photos, team portraits), optimized at build time
- …
Directoryconfig/ site-wide settings
- config.toml site name, URL, contact details, forms, SEO, cookies
- fonts.json fonts
- language.json languages and their text direction
- menu.en.json header and footer links (English)
- menu.fr.json header and footer links (French)
- menu.ar.json header and footer links (Arabic)
- social.json social media links
Directorycontent/ all text, images, and options
Directorysections/ default content of every section
Directoryenglish/
- …
Directoryfrench/
- …
Directoryarabic/
- …
Directoryhomepage/ the 4 homepages
- …
Directoryservices/ projects/ careers/ blog/ … one folder per page or collection
- …
Directoryi18n/ small interface text (button labels, form messages, footer text)
- en.json
- fr.json
- ar.json
Directorylayouts/
- Base.astro the page shell (head, header, footer, cookie banner, scripts)
Directorycomponents/
Directorysections/ one component per section
- …
Directorycards/ cards used inside sections
- …
Directorywidgets/ smaller parts (quote form, newsletter form, form setup notice, calculator, page header, cookie banner, mobile menu panel)
- …
Directoryglobal/ footer, logo, section titles
Directoryheader/ header layouts, top bar, announcement strip, menus, language switch
- …
Directoryfooter/ the four footer layouts, the call-to-action band, the AI row, the theme credit, and their line art
- …
Directoryseo/ head tags
- …
Directoryutilities/ small shared parts (optimized image, count-up number)
- …
Directoryhelpers/ icon components
- …
Directoryshortcodes/ components you can use inside MDX files
- …
Directorylib/ helper code (content loading, i18n, SEO, the AI files, the calculator formula, and the
[site]and[forms]setup checks)- …
Directorypages/
Directory[…lang]/ one file per route (which sections a page shows, in which order), plus
llms.txtandllms-full.txt- …
- […path].md.ts the Markdown copies of pages
- robots.txt.ts
robots.txt - 404.astro the default 404 page
Directoryplugins/ build plugins
- …
Directorystyles/
- theme.css colors, type scale, breakpoints
- base.css components.css navigation.css rtl.css … global styles
Directorytypes/ TypeScript types
- …
- content.config.ts fields allowed in each collection
- sections.schema.ts fields allowed in each section
- AGENTS.md SKILLS.md CLAUDE.md GEMINI.md instructions for AI assistants
- README.md CHANGELOG.md setup notes and what changed in each version
- astro.config.mjs
- netlify.toml vercel.json vercel.sh wrangler.toml hosting settings
- package.json package-lock.json
What Differs By Edition
The tree above is the Astro edition. The other editions change these parts:
| Part | Astro | Tina | Sanity |
|---|---|---|---|
src/content/, src/i18n/, src/config/menu.*.json | Yes | Yes. The text pages and the listing pages of services, projects, and blog are .mdx instead of .md | Not in the zip: this content is in your Sanity project |
tina/, scripts/tina/, scripts/cms/, src/lib/tina/, src/layouts/components/tina/, public/admin/ | No | Yes | No |
sanity/, sanity.config.ts, sanity.cli.ts, scripts/sanity/, src/lib/sanity/, src/sanity-routes/, src/middleware.ts | No | No | Yes |
.env.example | No | Yes | Yes |
The Three Layers
Ecozen keeps three jobs apart. Knowing which layer you need saves a lot of searching:
| Layer | Folder | Decides | You edit it to… |
|---|---|---|---|
| Content | src/content/ | What the page says: text, images, links, options | Change copy, lists, buttons, layouts |
| Pages | src/pages/[...lang]/ | Which sections a page shows and in which order | Reorder, add, or remove sections |
| Design | src/layouts/, src/styles/ | How each section looks and behaves | Change markup, styles, or behavior |
Global settings sit beside them in src/config/.
How Content Folders Are Named
Every content folder has one subfolder per language, and a few file name rules:
english/,french/, andarabic/hold the same files. Each language reads only its own folder, so keep them all in step when you add or rename a file.-index.mdis the content of a list or landing page, for examplesrc/content/projects/english/-index.mdfor/projects/.- Every other file is one entry. Its name becomes the URL unless the file sets
customSlug:src/content/careers/english/electrician.mdis/careers/electrician/, andsrc/content/services/english/service-01.mdx(withcustomSlug: "residential-solar") is/services/residential-solar/. - Files that start with
_are ignored.src/content/_file_format.mdexplains most page frontmatter fields; the full list is thepageschema insrc/content.config.ts.
Path Shortcuts In Code
Component files import each other through shortcuts defined in tsconfig.json:
| Shortcut | Real folder |
|---|---|
@/components/* | src/layouts/components/* |
@/shortcodes/* | src/layouts/shortcodes/* |
@/helpers/* | src/layouts/helpers/* |
@/* | src/* |
There is no src/components/ folder: @/components/sections/HeroSection.astro is src/layouts/components/sections/HeroSection.astro.