Linux cesa-www-main 6.1.0-49-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
Apache/2.4.68 (Debian)
Server IP : 10.218.0.2 & Your IP : 216.73.216.28
Domains :
Cant Read [ /etc/named.conf ]
User : www-data
Terminal
Auto Root
Create File
Create Folder
Localroot Suggester
Backdoor Destroyer
Readme
/
usr /
share /
doc /
apache2-doc /
manual /
ru /
rewrite /
Delete
Unzip
Name
Size
Permission
Date
Action
access.html
5.12
KB
-rw-r--r--
2026-06-12 05:08
advanced.html
5.55
KB
-rw-r--r--
2026-06-12 05:08
avoid.html
28.15
KB
-rw-r--r--
2026-06-12 05:08
flags.html
55.44
KB
-rw-r--r--
2026-06-12 05:08
htaccess.html
24.1
KB
-rw-r--r--
2026-06-12 05:08
index.html
7.69
KB
-rw-r--r--
2026-06-12 05:08
intro.html
27.13
KB
-rw-r--r--
2026-06-12 05:08
proxy.html
4.76
KB
-rw-r--r--
2026-06-12 05:08
remapping.html
39.84
KB
-rw-r--r--
2026-06-12 05:08
rewritemap.html
28.88
KB
-rw-r--r--
2026-06-12 05:08
tech.html
17.87
KB
-rw-r--r--
2026-06-12 05:08
vhosts.html
12.73
KB
-rw-r--r--
2026-06-12 05:08
Save
Rename
<!DOCTYPE html SYSTEM "about:legacy-compat"> <html lang="en"><head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta content="width=device-width, initial-scale=1" name="viewport"> <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX This file is generated from xml source: DO NOT EDIT XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --> <title>Per-directory Rewrites - Apache HTTP Server Version 2.4</title> <link href="../../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet"> <link href="../../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size"> <link href="../../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css"><link rel="stylesheet" type="text/css" href="../../style/css/prettify.css"> <script src="../../style/scripts/prettify.min.js"> </script> <link href="../../images/favicon.png" rel="shortcut icon"></head> <body id="manual-page"><div id="page-header"> <p class="menu"><a href="../mod/index.html">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p> <p class="apache">Apache HTTP Server Version 2.4</p> <img alt="" src="../../images/feather.png"></div> <div class="up"><a href="./index.html"><img title="<-" alt="<-" src="../../images/left.gif"></a></div> <div id="path"> <a href="https://www.apache.org/">Apache</a> > <a href="https://httpd.apache.org/">HTTP Server</a> > <a href="https://httpd.apache.org/docs/">Documentation</a> > <a href="../index.html">Version 2.4</a> > <a href="./index.html">Rewrite</a></div><div id="page-content"><div id="preamble"><h1>Per-directory Rewrites</h1> <button aria-label="Toggle language list" class="lang-toggle"><svg xmlns="http://www.w3.org/2000/svg" stroke-width="2" stroke="currentColor" fill="none" viewBox="0 0 24 24" height="16" width="16"><circle r="10" cy="12" cx="12"/><line y2="12" x2="22" y1="12" x1="2"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg></button> <div class="toplang"> <p><span>Available Languages: </span><a href="../../en/rewrite/htaccess.html" title="English"> en </a> | <a href="../../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p> </div> <p>Using <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> in <code>.htaccess</code> files is one of the most common - and most confusing - <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory</a> configurations. This document explains the key differences between using rewrite rules in server configuration versus <code>.htaccess</code> files, and provides practical guidance for avoiding the most common pitfalls.</p> <p>For the low-level technical details of how <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> processes rules in per-directory context, see the <a href="tech.html#InternalAPI">Technical Details</a> document.</p> </div> <div id="quickview"><ul id="toc"><li><img alt="" src="../../images/down.gif"> <a href="#prerequisites">Prerequisites: AllowOverride</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#path-stripping">What URL does the rule see?</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#rewritebase">When you need RewriteBase</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#loops">The [L] flag and looping</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#rewritemap-restriction">RewriteMap cannot be declared in .htaccess</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#context-restrictions">Which contexts support rewrite rules?</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#inheritance">Rule inheritance with RewriteOptions</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#debugging">Debugging .htaccess rewrite rules</a></li> <li><img alt="" src="../../images/down.gif"> <a href="#caching">Browser caching of 301 redirects</a></li> </ul><h3>See also</h3><ul class="seealso"><li><a href="../mod/mod_rewrite.html">Module documentation</a></li><li><a href="intro.html">mod_rewrite introduction</a></li><li><a href="remapping.html">Redirection and remapping</a></li><li><a href="vhosts.html">Virtual hosts</a></li><li><a href="rewritemap.html">Using RewriteMap</a></li><li><a href="avoid.html">When not to use mod_rewrite</a></li><li><a href="flags.html">RewriteRule Flags</a></li><li><a href="tech.html">Technical details</a></li><li><a href="../mod/mod_rewrite.html#what_is_matched">What is matched?</a></li></ul></div> <div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="prerequisites">Prerequisites: AllowOverride <a title="Permanent link" href="#prerequisites" class="permalink">¶</a></h2> <p>Before <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> directives in a <code>.htaccess</code> file will be processed at all, the server configuration must permit them. This requires:</p> <pre class="prettyprint lang-config"><Directory "/var/www/htdocs"> AllowOverride FileInfo </Directory></pre> <p>Without at least <code>AllowOverride FileInfo</code> (or <code>AllowOverride All</code>), any <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> directives in <code>.htaccess</code> files are silently ignored. If your rules don't appear to be doing anything, this is the first thing to check.</p> <p>Additionally, either <code>Options FollowSymLinks</code> or <code>Options SymLinksIfOwnerMatch</code> must be enabled for the directory in question. Because a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> can map a URL to an arbitrary filesystem path - functionally equivalent to a symbolic link - <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> refuses to operate in per-directory context unless one of these options is set. Without it, you will see the following error:</p> <div class="example"><p><code> AH00670: Options FollowSymLinks and SymLinksIfOwnerMatch are both off, so the RewriteRule directive is also forbidden due to its similar ability to circumvent directory restrictions </code></p></div> <p>This restriction applies to both <code>.htaccess</code> files and <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> blocks.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="path-stripping">What URL does the rule see? <a title="Permanent link" href="#path-stripping" class="permalink">¶</a></h2> <p>In server or virtualhost context, the <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> pattern is matched against the full URL-path, starting with a leading slash. In <code>.htaccess</code> context, the directory prefix is <strong>stripped</strong>.</p> <p>For example, if your <code>.htaccess</code> is in <code>/var/www/htdocs/app/</code> and a request comes in for <code>/app/products/widget</code>, the RewriteRule sees only <code>products/widget</code> - no leading slash, no <code>/app/</code> prefix.</p> <p>This means you must write your patterns differently depending on where the rule lives:</p> <table class="bordered"> <tr> <th>Location of rule</th> <th>Rule</th> </tr> <tr> <td>VirtualHost section</td> <td><code>RewriteRule "^/app/products/(.+)$" "/app/shop.php?item=$1"</code></td> </tr> <tr> <td>.htaccess in /var/www/htdocs/app/</td> <td><code>RewriteRule "^products/(.+)$" "shop.php?item=$1"</code></td> </tr> </table> <p>Note that the <code>.htaccess</code> version has no leading slash in either the pattern or the substitution. This is the single most common source of confusion with per-directory rewriting.</p> <p>When a substitution is made in per-directory context, Apache issues a new internal subrequest with the rewritten URL, restarting request processing from the top. If the substitution is a relative path, the <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> directive determines what URL-path prefix is prepended. This subrequest mechanism is also why rules can loop — see <a href="#loops">below</a>.</p> <div class="warning"><h3>Do not start .htaccess patterns with /</h3> <p>Because the directory prefix (including the trailing slash) is stripped before matching, patterns in <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a> will <em>never</em> match a leading slash. A pattern beginning with <code>^/</code> will never match in this context. A rule like <code>RewriteRule "^/foo" ...</code> will silently fail to match anything when placed in a <code>.htaccess</code> file.</p> </div> <p>If you need to match against the full original URL-path (including the directory prefix), use <code>%{REQUEST_URI}</code> in a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code>:</p> <pre class="prettyprint lang-config">RewriteCond "%{REQUEST_URI}" "^/admin/" RewriteRule "^.*$" "-" [F]</pre> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="rewritebase">When you need RewriteBase <a title="Permanent link" href="#rewritebase" class="permalink">¶</a></h2> <p>When <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> makes a substitution in <code>.htaccess</code> context, it needs to turn the relative result back into a full URL-path. The <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> directive tells it what prefix to prepend.</p> <p>By default, <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> is set to the physical directory path of the <code>.htaccess</code> file. In most cases, this does the right thing, and you don't need to set it explicitly. But there are situations where you do:</p> <ul> <li><strong>Alias or symlink:</strong> If the directory is reached via an <code class="directive"><a href="../mod/mod_alias.html#alias">Alias</a></code> or a symlink, the URL path and the filesystem path differ, and <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> must be set to the URL path.</li> <li><strong>Subdirectory applications:</strong> A common pattern for PHP frameworks is to place a <code>.htaccess</code> in a subdirectory (say, <code>/var/www/htdocs/myapp/</code>) and route all requests to a front controller:</li> </ul> <pre class="prettyprint lang-config"># In /var/www/htdocs/myapp/.htaccess RewriteEngine On RewriteBase "/myapp/" RewriteCond "%{REQUEST_FILENAME}" !-f RewriteCond "%{REQUEST_FILENAME}" !-d RewriteRule "^(.*)$" "index.php" [L]</pre> <div class="note">For this particular use case - routing all unmatched requests to a front controller - the <a href="avoid.html#fallback-resource">FallbackResource</a> directive is a simpler and more efficient alternative to mod_rewrite.</div> <p>Without the <code>RewriteBase "/myapp/"</code> line, the rewritten URL might resolve incorrectly, because <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> would prepend the filesystem path rather than the URL path.</p> <p>If you're using absolute URLs (starting with <code>/</code> or <code>http://</code>) in your substitutions, <code class="directive"><a href="../mod/mod_rewrite.html#rewritebase">RewriteBase</a></code> has no effect - it only applies to relative substitutions.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="loops">The [L] flag and looping <a title="Permanent link" href="#loops" class="permalink">¶</a></h2> <p>In server context, the <code>[L]</code> flag means "stop processing the ruleset." In <code>.htaccess</code> context, it means something subtly different: "stop processing the ruleset <em>for this pass</em>." After the substitution is made, Apache re-processes the request from the top - including re-applying the <code>.htaccess</code> rules. This can lead to infinite loops.</p> <p>Consider this rule:</p> <pre class="prettyprint lang-config"># In .htaccess - this may loop! RewriteRule "^(.*)$" "/index.php?q=$1" [L]</pre> <p>On the first pass, a request for <code>/hello</code> is rewritten to <code>/index.php?q=hello</code>. Then the request is re-processed, and now <code>index.php</code> matches <code>^(.*)$</code> again, rewriting to <code>/index.php?q=index.php</code>. This continues until Apache hits its internal redirect limit and returns a 500 error. You will see the following in the error log:</p> <div class="example"><p><code> AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace. </code></p></div> <p>There are several ways to break the loop:</p> <p><strong>Option 1: Use the [END] flag</strong> (recommended)</p> <pre class="prettyprint lang-config">RewriteRule "^(.*)$" "/index.php?q=$1" [END]</pre> <p>The <code>[END]</code> flag (available since Apache 2.3.9) stops <em>all</em> further rewrite processing, including subsequent passes. It is the cleanest way to prevent loops.</p> <p><strong>Option 2: Add a condition to skip already-rewritten URLs</strong></p> <pre class="prettyprint lang-config">RewriteCond "%{REQUEST_FILENAME}" !-f RewriteCond "%{REQUEST_FILENAME}" !-d RewriteRule "^(.*)$" "/index.php?q=$1" [L]</pre> <p>Since <code>index.php</code> exists as a file, the <code>!-f</code> condition causes the rule to be skipped on the second pass.</p> <p><strong>Option 3: Check THE_REQUEST</strong></p> <pre class="prettyprint lang-config">RewriteCond "%{THE_REQUEST}" "!index\.php" RewriteRule "^(.*)$" "/index.php?q=$1" [L]</pre> <p>The <code>%{THE_REQUEST}</code> variable contains the original request line as sent by the client, which is not modified by <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code>. Checking it prevents the rule from matching rewritten URLs.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="rewritemap-restriction">RewriteMap cannot be declared in .htaccess <a title="Permanent link" href="#rewritemap-restriction" class="permalink">¶</a></h2> <p>The <code class="directive"><a href="../mod/mod_rewrite.html#rewritemap">RewriteMap</a></code> directive can only be declared in server or virtualhost context - not in <code>.htaccess</code> files or <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code> blocks. However, once a map is declared in the server configuration, you <em>can</em> use it from a <code>.htaccess</code> file:</p> <pre class="prettyprint lang-config"># In apache2.conf or a VirtualHost RewriteMap product2id "txt:/etc/apache2/productmap.txt"</pre> <pre class="prettyprint lang-config"># In .htaccess - using the map declared above RewriteEngine On RewriteRule "^product/(.+)$" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]</pre> <p>This restriction exists because <code>.htaccess</code> files are parsed on every request, and map initialization (especially for <code>dbm:</code>, <code>dbd:</code>, and <code>prg:</code> map types) would be prohibitively expensive to repeat each time.</p> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="context-restrictions">Which contexts support rewrite rules? <a title="Permanent link" href="#context-restrictions" class="permalink">¶</a></h2> <p>Rewrite rules are supported in <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a> (<a href="../howto/htaccess.html">.htaccess</a> files, <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>, and <code class="directive"><a href="../mod/core.html#if"><If></a></code> blocks).</p> <p>Although rewrite rules are syntactically permitted in <code class="directive"><a href="../mod/core.html#location"><Location></a></code> and <code class="directive"><a href="../mod/core.html#files"><Files></a></code> sections (including their regex counterparts), this is unsupported and should never be necessary. Relative substitutions, in particular, are likely to break in these contexts.</p> <div class="warning"><h3>These containers silently change rewrite behavior</h3> <p>Placing a <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> inside a <code class="directive"><a href="../mod/core.html#directory"><Directory></a></code>, <code class="directive"><a href="../mod/core.html#if"><If></a></code>, or <code class="directive"><a href="../mod/core.html#location"><Location></a></code> block — even inside a <code class="directive"><a href="../mod/core.html#virtualhost"><VirtualHost></a></code> in the main server config — silently switches to <a class="glossarylink" href="../glossary.html#perdirectory" title="see glossary">per-directory context</a> behavior. This means the leading slash is stripped from the URL before pattern matching, substitutions trigger an internal redirect (with loop risk), and the <a href="../rewrite/flags.html#flag_l">[L]</a> flag no longer truly stops processing — use <a href="../rewrite/flags.html#flag_end">[END]</a> instead.</p> </div> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="inheritance">Rule inheritance with RewriteOptions <a title="Permanent link" href="#inheritance" class="permalink">¶</a></h2> <p>By default, <code class="module"><a href="../mod/mod_rewrite.html">mod_rewrite</a></code> rules are <strong>not inherited</strong> by subdirectories. If you define rules in <code>/var/www/htdocs/.htaccess</code>, they apply to that directory only. A <code>.htaccess</code> file in a subdirectory starts with an empty ruleset, unless you explicitly enable inheritance.</p> <p>The <code class="directive"><a href="../mod/mod_rewrite.html#rewriteoptions">RewriteOptions</a></code> directive controls this behavior:</p> <dl> <dt><code>RewriteOptions Inherit</code></dt> <dd>Rules from the parent context are appended to the current ruleset. The child's rules are processed first, then the parent's. Use this when a subdirectory needs to add its own rules while keeping the parent's rules active.</dd> <dt><code>RewriteOptions InheritBefore</code></dt> <dd>Like <code>Inherit</code>, but the parent's rules are processed <em>before</em> the child's. This is useful when the parent defines a front-controller pattern and the child needs to add exceptions. Available since Apache 2.4.8.</dd> <dt><code>RewriteOptions InheritDown</code></dt> <dd>Set this in the parent context to force all child contexts to inherit the parent's rules, without requiring each child to specify <code>Inherit</code>. Available since Apache 2.4.8.</dd> <dt><code>RewriteOptions InheritDownBefore</code></dt> <dd>Like <code>InheritDown</code>, but forces the parent's rules to run before the child's. Available since Apache 2.4.8.</dd> <dt><code>RewriteOptions IgnoreInherit</code></dt> <dd>Set this in a child context to opt out of inheritance that was forced by a parent's <code>InheritDown</code>. Available since Apache 2.4.8.</dd> <dt><code>RewriteOptions MergeBase</code></dt> <dd>When inheritance is enabled, the <code>RewriteBase</code> from each context is used for rules defined in that context, rather than applying the child's <code>RewriteBase</code> to all inherited rules. Available since Apache 2.4.26.</dd> </dl> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="debugging">Debugging .htaccess rewrite rules <a title="Permanent link" href="#debugging" class="permalink">¶</a></h2> <p>When <code>.htaccess</code> rules are not doing what you expect, the rewrite log is your most important tool. Enable it at the appropriate trace level:</p> <pre class="prettyprint lang-config">LogLevel alert rewrite:trace3</pre> <p>This produces detailed output in the error log showing exactly how each rule is processed - what pattern was matched against, whether conditions succeeded or failed, and what substitution was made. The per-directory context and path stripping behavior will be visible in these log entries.</p> <div class="warning">Do not leave trace-level logging enabled in production. It generates a large volume of output and will affect performance.</div> </div><div class="top"><a href="#page-header"><img alt="top" src="../../images/up.gif"></a></div> <div class="section"> <h2 id="caching">Browser caching of 301 redirects <a title="Permanent link" href="#caching" class="permalink">¶</a></h2> <p>When you issue a <code>301 Moved Permanently</code> redirect (via <code>[R=301]</code> or <code class="directive"><a href="../mod/mod_alias.html#redirect permanent">Redirect permanent</a></code>), the browser is allowed to cache that response indefinitely. This means that even after you fix an incorrect redirect rule in your configuration, returning visitors may continue to be sent to the old (wrong) destination without ever contacting your server again.</p> <p>While debugging redirect rules, use <code>[R=302]</code> (temporary redirect) instead of <code>[R=301]</code>. Switch to 301 only after you have confirmed the rule is correct. If you have already issued an incorrect 301, affected users will need to clear their browser cache (or use a private/incognito window) to see the corrected behavior.</p> <div class="note">Search engines also cache 301 redirects. An incorrect 301 may take days or weeks to be re-crawled, even after the configuration is fixed. This is another reason to test with 302 first.</div> </div></div> <div class="bottomlang"> <p><span>Available Languages: </span><a href="../../en/rewrite/htaccess.html" title="English"> en </a> | <a href="../../fr/rewrite/htaccess.html" hreflang="fr" rel="alternate" title="Français"> fr </a></p> </div><div id="footer"> <p class="apache">Copyright 2026 The Apache Software Foundation.<br>Licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p> <p class="menu"><a href="../mod/index.html">Modules</a> | <a href="../mod/quickreference.html">Directives</a> | <a href="https://cwiki.apache.org/confluence/display/httpd/FAQ">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a> | <a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2">Report a bug</a></p></div><script><!--//--><![CDATA[//><!-- if (typeof(prettyPrint) !== 'undefined') { prettyPrint(); } var langToggle = document.querySelector('.lang-toggle'); var topLang = document.querySelector('.toplang'); if (langToggle && topLang) { langToggle.addEventListener('click', function() { topLang.classList.toggle('open'); }); } var qv = document.getElementById('quickview'); if (qv) { document.body.appendChild(qv); var qvBtn = document.createElement('button'); qvBtn.className = 'qv-toggle'; qvBtn.setAttribute('aria-label', 'Toggle page navigation'); qvBtn.innerHTML = '☰'; document.body.appendChild(qvBtn); qvBtn.addEventListener('click', function() { var isOpen = qv.classList.toggle('open'); if (isOpen) { qv.style.top = window.scrollY + 10 + 'px'; } }); window.addEventListener('scroll', function() { qv.classList.remove('open'); }); } //--><!]]></script> </body></html>