# =============================================================================
# .htaccess — reference copy of the DEFAULT (Option A: package in its own folder)
#
# This is the DEFAULT and matches a straight extraction of the zip into its own
# folder, e.g. public_html/aiseo/. It forwards every request into public/
# and blocks everything that must not be web-readable.
#
# NO EDITING REQUIRED. There is deliberately no RewriteBase: in a .htaccess the
# rewrite target is already relative to this directory, so the folder can be
# renamed or moved without touching this file.
#
# Verified against real Apache 2.4 with AllowOverride All:
# /aiseo/ 200 (app)
# /aiseo/integrations 200 (routed)
# /aiseo/assets/css/tokens.css 200 (served from public/assets)
# /aiseo/setup-env.php 200 (writes .env — delete after use)
# /aiseo/migrate-web.php 200 (creates tables — delete after use)
# /aiseo/preflight.php 200 (diagnostic — delete after use)
# /aiseo/.env 403
# /aiseo/bootstrap.php 403
# /aiseo/src/Core/Env.php 403
# /aiseo/config/paths.php 403
# /aiseo/var/logs/app.log 403
#
# If the front controller instead sits AT this folder (index.php beside this
# file), use deploy/htaccess-B-front-controller-at-root.txt instead.
# =============================================================================
RewriteEngine On
# ---- blocks, before anything can be forwarded --------------------------
# Order matters. A forwarding rule that runs first would hand a source path
# to the front controller, which answers 200 and makes an exposure look fine.
# every dotfile: .env, .git, .htaccess, .gitignore
RewriteRule ^\. - [F,L]
RewriteRule ^bootstrap\.php$ - [F,L]
RewriteRule ^composer\.(json|lock)$ - [F,L]
RewriteRule ^(src|templates|config|bin|db|tests|var|storage|render-service|deploy|node_modules|vendor)(/|$) - [F,L]
# numbered folders (1-docs, 3-source-code, 4-…) are private by default, so a
# new one you add later is not public by accident
RewriteRule ^[0-9]+-[A-Za-z0-9_-]+(/|$) - [F,L]
# ---- the three temporary setup tools -----------------------------------
# setup-env.php (writes .env), migrate-web.php (creates the tables) and
# preflight.php (diagnostics). They live at the app root and MUST stay
# reachable or they cannot do their job. Delete all three once the app runs —
# that is the protection, not a rule that also locks you out.
RewriteRule ^(setup-env|preflight|migrate-web)\.php$ - [L]
# ---- forward into public/ ----------------------------------------------
# Already inside public/: let public/.htaccess take it from here.
RewriteCond %{REQUEST_URI} /public/
RewriteRule ^ - [L]
RewriteRule ^(.*)$ public/$1 [L]
# Belt and braces for hosts where mod_rewrite is unavailable.
Require all denied
Order allow,deny
Deny from all
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set X-Frame-Options "SAMEORIGIN"
# An internal tool. Keep it out of every index, AI crawlers included.
Header always set X-Robots-Tag "noindex, nofollow, noarchive"
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
# If your host answers with a 500 to this line, AllowOverride does not include
# Options. Delete just this line; nothing else depends on it.
Options -Indexes