- Home
- Documentation
- Files, folders and URLs
Files, folders and URLs
Contents
- The eclair folder tree
- How is a page served?
- What does the data folder contain?
- The cache and media folders
- cache/
- media/
- What goes in eclair-config.php?
- The .htaccess rules explained
- The Nginx configuration
- What permissions should files and folders have?
- Which files and folders should you back up?
- The URLs generated by Éclair
- Content URLs
- Frequently asked questions about files
Contents
- The eclair folder tree
- How is a page served?
- What does the data folder contain?
- The cache and media folders
- cache/
- media/
- What goes in eclair-config.php?
- The .htaccess rules explained
- The Nginx configuration
- What permissions should files and folders have?
- Which files and folders should you back up?
- The URLs generated by Éclair
- Content URLs
- Frequently asked questions about files
Éclair has no database: everything that makes up your site lives in files and folders you can see over FTP. This reference describes the file tree, the role of each file in data/, the settings in eclair-config.php, the .htaccess and Nginx rules, the permissions to set, what to back up and every URL the site generates on its own.
The eclair folder tree
The files and folders below are what you upload to your hosting's public folder (public_html, www…).
eclair/
├── index.php front controller: serves the cache without loading the application
├── .htaccess rewriting, protections, compression, browser caching
├── eclair-config.exemple.php template for the optional advanced settings
├── app/ Éclair's code (never reachable from the web)
│ ├── bootstrap.php startup: PHP version, eclair-config.php, loading
│ ├── manifest.php original fingerprints for the integrity check
│ ├── lib/ classes: Content, Blocks, Seo, Analyzer, Media, Auth, Mcp…
│ ├── admin/views/ admin screens (.php.gz in the archive)
│ ├── install/ setup wizard and “Installation locked” screen
│ ├── lang/ admin translations (6 languages, compressed JSON)
│ └── theme/ public site templates, theme.css, themes/, directions.css
├── assets/
│ ├── admin/ admin CSS and JavaScript
│ └── site/site.js the public site's only script (1.2 KB compressed)
├── data/ content, settings, accounts: never public
├── cache/ generated pages: never public
└── media/ uploaded images, site icons, heading font
app/ and assets/ contain the code: an update replaces them. Your data is in data/ and media/, which updates never touch. Next to the eclair folder, the official archive also contains the LISEZ-MOI.txt, LICENSE.txt and THIRD-PARTY-NOTICES.txt files: there's no need to upload them to your hosting.
How is a page served?

- Every page request arrives at
index.php; images, CSS and scripts are served directly by the server. For a read (GETorHEAD),index.phpreadscache/runtime.php: whether the cache is on, its expiry date, and the required domain and HTTPS. - If the page exists in
cache/pages/, it's sent as is, with its ETag; a browser that already has it gets a304 Not Modifiedresponse. - Otherwise,
app/bootstrap.phpstarts the application: it checks the PHP version, readseclair-config.phpif it exists, then routes the request to the installer, the admin, the form, the MCP connector or the site. The generated page is cached for the next visits.
The code is covered in detail in Éclair's architecture.
What does the data folder contain?
Each file in data/ is a .php file that starts with the line <?php exit; ?>, followed by JSON data. Even if a server ignored .htaccess files, opening one in a browser would display nothing. Writes are atomic (a temporary file, then a rename) and the files are private.
| File or folder | Contents | In the ZIP backup |
|---|---|---|
site.php | All the settings from the Settings tabs | Yes |
users.php | Accounts, password hashes, two-factor authentication | Yes |
keys.php | Secret keys created at installation (site secret, IndexNow key) | Yes |
vault.php | The AI assistant's API keys, encrypted | No |
index.php | A summary of all content, to list it and find a URL quickly | Yes |
content/ | One file per page, post or product | Yes |
revisions/ | The 20 latest versions of each piece of content | Yes |
search.php | The text of your content, for site search | Yes |
media.php | The media library register: files, dimensions, alt texts | Yes |
categories.php, menus.php, redirects.php | Categories, menus and redirects | Yes |
custom-css.php | Your custom CSS | Yes |
inbox.php and messages/ | The contact form inbox, 500 messages at most | Yes |
indexnow.php | Date and result of the last IndexNow submission | Yes |
logs/ | Security log and technical errors, 1 MB at most each | Yes |
sessions/ | Open sessions, stored under a hashed name | No |
limits/ | Brute-force and anti-spam counters | No |
ai/ | Spending, conversations (30 per person), suggestions, undo data, MCP connections | No |
install-window.php | Start of the 2-hour installation window, deleted when installation is complete | Not applicable |
reset.php | “Forgot password” recovery file, created by you, deleted automatically | No |
The cache and media folders
cache/
| Item | Role |
|---|---|
runtime.php | Fast-path settings: cache on or off, expiry at the next scheduled post, required domain and HTTPS |
pages/ | One generated page per URL, named after the md5 hash of its path: a line of headers and ETag, then the HTML |
backup-….zip | A backup being downloaded, deleted afterwards; if the download was interrupted, it's erased when the cache is cleared, at least an hour later |
The cache clears itself on every change, and at the scheduled time for a scheduled post. To clear it by hand: Settings › Advanced › Clear cache.
media/
| Item | Role |
|---|---|
2026/11/… | Uploaded images, sorted by year and month |
photo.jpg, .png, .webp or .gif | The re-encoded image, 2,000 px wide at most, with no EXIF or GPS data (with the GD extension) |
photo-480.webp to photo-1600.webp | WebP versions at 480, 800, 1200 and 1600 px (only those smaller than the original), plus a WebP version at the image's own size |
photo-og.jpg | 1200 × 630 share image, created the first time it's needed |
site/icon-32.png, icon-180.png, icon-192.png, icon-512.png | Site icons: favicon and mobile home screen |
fonts/ | Your art direction's heading font (.woff2), downloaded once |
The media/.htaccess file only allows images: no scripts, HTML pages, SVG or file listings, with a security policy that forbids any active content. Uploads are covered in detail in Images and the media library.
What goes in eclair-config.php?
This optional file sits next to index.php. Copy eclair-config.exemple.php under the name eclair-config.php, then uncomment what you need. It's read when the application starts, before anything else, and the integrity check doesn't flag it as an unknown file.
<?php
defined('ECLAIR') || exit;
// Error details, while you solve a problem:
// define('ECLAIR_DEBUG', true);
// Data outside the public folder (move the data folder first):
// define('ECLAIR_DATA', '/home/myaccount/eclair-data');
// Stronger protection for API keys, to set before saving them:
// define('ECLAIR_SECRET', 'a-long-secret-phrase');
| Constant | Effect | Precaution |
|---|---|---|
ECLAIR_DEBUG | Shows error details | Also turns off the static cache: delete the line once the problem is solved |
ECLAIR_DATA | Stores the data in another location (absolute path) | Move data/ first, and remember to back up the new location |
ECLAIR_SECRET | Adds a secret phrase to the encryption of API keys | Set it before saving your keys; if you add or change it later, you have to paste them again |
The code also recognizes two technical constants that aren't in the official guide: ECLAIR_AI_ENDPOINTS (a replacement URL for an AI service, for a gateway or for tests) and ECLAIR_FONTS_URL (the font source, Fontsource via cdn.jsdelivr.net by default). Only use them if you know why. ECLAIR_VERSION and ECLAIR_ROOT are set by index.php.
The .htaccess rules explained
Éclair's .htaccess file works at the root of a domain as well as in a subfolder. It only uses directives allowed on shared hosting: no Options, no php_flag. Here is its rewriting section:
RewriteEngine On
# RewriteBase /
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^(app|data|cache)(/|$) - [R=404,L]
RewriteRule (^|/)\.(?!well-known/) - [R=404,L]
RewriteRule ^(?!index\.php$).*\.(php\d?|phtml|phar|inc)$ - [R=404,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L,QSA]
RewriteBase /stays commented out: uncomment it only if your host requires it, which is rare.- The two
Authorizationlines pass PHP the authorization header that some hosts strip. The MCP connector needs it. app/,data/andcache/return a 404 from the web.- Hidden files (
.git,.env…) return a 404, except for the.well-knownfolder. - No PHP script runs except
index.php. - Everything that isn't an existing file goes through
index.php, even a folder: no file listing is ever shown.
The rest of the file turns on Brotli or Gzip compression for HTML pages, CSS stylesheets, JavaScript, JSON and XML data, RSS feeds, SVG images and Markdown, sets one-year browser caching for images, CSS, scripts and fonts (Cache-Control: public, max-age=31536000, immutable), and declares the WebP, AVIF and WOFF2 types. The app/, data/ and cache/ folders also have their own .htaccess that denies all access, so the protection is doubled.
The Nginx configuration
Nginx ignores .htaccess files: reproduce these rules in your site's server block. This is the configuration given in the official guide.
location ~ ^/(app|data|cache)(/|$) { return 404; }
location ~ /\.(?!well-known/) { return 404; }
location ^~ /media/ {
location ~* \.(php\d?|phtml|phar|s?html?|svgz?|xml|js)$ { return 404; }
add_header X-Content-Type-Options nosniff;
expires 1y;
}
location ~* \.(webp|avif|jpe?g|png|gif|ico|css|js|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location / { try_files $uri /index.php$is_args$args; }
location = /index.php {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
location ~ \.php$ { return 404; }
- The first two rules close off the internal folders and hidden files, except
.well-known. - The
/media/block refuses scripts, HTML pages, SVG and XML, and caches files for a year. try_filessends everything that isn't an existing file toindex.php.- Only
index.phpis handed to PHP-FPM: adaptfastcgi_passto your server's socket. - For the AI assistant to stream its answers as they're written, add
fastcgi_buffering off;to the PHP block.
HTTPS, proxies and CDNs are covered in Nginx, VPS, proxy and CDN.
What permissions should files and folders have?
- PHP must be able to write to
data/,cache/andmedia/. The setup wizard checks each of them (Folder “data” is writable) and, if a check fails, advises giving write permission (755) via FTP. - Éclair then creates its data files with 0600 permissions (readable only by the account that runs PHP), its subfolders of
data/andcache/with 0700, and those ofmedia/with 0755. - Avoid 777 permissions, which let any account on the server write. If 755 isn't enough, ask your host which account PHP runs under.
Which files and folders should you back up?
| What to back up | Why | How |
|---|---|---|
data/ | Content, settings, accounts, custom CSS | Security › Download a backup, or FTP |
media/ | Images, icons, heading font | Same ZIP backup, or FTP |
eclair-config.php | If you created one | FTP |
Modified templates in app/theme/ | An update replaces them | FTP, before every update |
Folder set by ECLAIR_DATA | If you moved your data | FTP |
The ZIP backup contains neither the API keys, nor the conversations and MCP connections, nor the sessions. After restoring to another server, paste your API keys again and reconnect Claude or ChatGPT. To restore, replace data/ and media/ with the ones from the backup (via FTP), then clear the cache from the admin.

The complete update procedure is in Advanced security and maintenance.
The URLs generated by Éclair
| URL | Content | When it exists |
|---|---|---|
/sitemap.xml | Site map with images and language versions | Always; empty if the site is hidden from search engines |
/robots.txt | Bot rules, including 30 AI bots, and the sitemap link | Always |
/llms.txt | Site map for AI | Publish /llms.txt option |
/llms-full.txt | All the content in Markdown | /llms.txt and /llms-full.txt options |
/feed.xml | RSS feed of the 20 latest posts, full text | Blog enabled |
/products.xml | Product feed for Google Merchant Center | Shop open |
/my-page.md, /index.md | Markdown version of a page, noindex, with its canonical URL | Markdown version of every page option, except for noindex pages |
/favicon.ico | 32 px icon | As soon as the site icon exists |
/search?q=… | Search results, noindex | Site search option |
/<key>.txt | IndexNow ownership proof | IndexNow enabled |
/_eclair/mcp | MCP connector | Allow MCP connections |
/_eclair/oauth/authorize, /token, /register | OAuth authorization for the connector | Same condition |
/.well-known/oauth-protected-resource, /.well-known/oauth-authorization-server, /.well-known/openid-configuration | OAuth discovery | Same condition |
/_eclair/contact | Receives the contact form | Always |
/_eclair/edit/<id> | The site's ✏️ Edit button, leading to the editor | Logged-in users |
/__eclair/ping | Rewriting test and site address verification | Always |
Content URLs
| Content | URL on an English-language site |
|---|---|
| Page | /my-page, or /parent/child for a subpage (4 levels at most) |
| Home page | /; the home page's own URL redirects to / |
| Post | /blog/my-post |
| Further blog pages | /blog/page/2 |
| Post category | /blog/my-category |
| Author page | /blog/author/first-last |
| Catalog | /shop, then /shop/page/2 |
| Product category, product | /shop/my-category, /shop/my-product |
| Admin | The URL chosen during installation |
The words in URLs follow the site's language: page in French and English, pagina in Spanish, Italian and Portuguese, seite in German; auteur, autor, author or autore; recherche, buscar, search, suche, cerca or pesquisa; boutique, tienda, shop, negozio or loja.
One URL per piece of content: Éclair 301-redirects variants with capital letters, a trailing slash, double slashes or index.php, as well as http to https when HTTPS is forced, and www or non-www once the official URL is verified.
Some words are reserved and can't be used as a page URL: app, data, cache, assets, media, index, admin, _eclair, __eclair, sitemap, robots, feed, llms, llms-full, favicon, wp-admin, wp-login, plus your admin URL, the blog URL, the search word and the shop URL once it's set up. The SEO side of these URLs is covered in SEO with Éclair.
Frequently asked questions about files
Can I delete the cache folder?
Don't delete the folder itself: it contains its own .htaccess protection. Use Settings › Advanced › Clear cache, which only erases the generated pages; they're recreated on the next visit.
Where are my posts stored?
In data/content/, one file per piece of content, with their 20 latest versions in data/revisions/. Images are in media/, sorted by year and month.
Can you put the data folder outside the public folder?
Yes, if your host allows it: move the data folder, then give its absolute path with ECLAIR_DATA in eclair-config.php. Add the new location to your backups.