<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: developer</title>
    <description>The latest articles on DEV Community by developer (@_dj_).</description>
    <link>https://dev.to/_dj_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1545542%2Fc3f521b0-26ca-41bb-a604-4dc9e756f184.jpg</url>
      <title>DEV Community: developer</title>
      <link>https://dev.to/_dj_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_dj_"/>
    <language>en</language>
    <item>
      <title>Fix: Qwik makes empty sitemap.xml</title>
      <dc:creator>developer</dc:creator>
      <pubDate>Tue, 02 Dec 2025 05:50:33 +0000</pubDate>
      <link>https://dev.to/_dj_/qwik-ad</link>
      <guid>https://dev.to/_dj_/qwik-ad</guid>
      <description>&lt;p&gt;Qwik or Qwik City generates the sitemap on local but an empty sitemap on production? This problem is not solved by following the &lt;a href="https://qwik.dev/docs/advanced/sitemaps/" rel="noopener noreferrer"&gt;official Qwik documentation&lt;/a&gt; because it's a different type of error.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fixing Empty Sitemap in Qwik Production with Node.js Adapter
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;When deploying a Qwik application using the &lt;strong&gt;Node.js adapter&lt;/strong&gt; (&lt;code&gt;nodeServerAdapter&lt;/code&gt;), the &lt;code&gt;sitemap.xml&lt;/code&gt; file works perfectly in local development but appears empty in production:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;urlset&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.sitemaps.org/schemas/sitemap/0.9"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/urlset&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This issue affects &lt;strong&gt;multiple Qwik projects&lt;/strong&gt; and is one of the most confusing deployment problems because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Local build works fine&lt;/li&gt;
&lt;li&gt;✅ Dev server serves sitemap correctly&lt;/li&gt;
&lt;li&gt;❌ Production sitemap is empty&lt;/li&gt;
&lt;li&gt;❌ No error messages or warnings&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Root Cause
&lt;/h2&gt;

&lt;p&gt;The Node.js adapter (&lt;code&gt;@builder.io/qwik-city/adapters/node-server&lt;/code&gt;) &lt;strong&gt;automatically runs Static Site Generation (SSG)&lt;/strong&gt; during the build process, even when you're building for SSR.&lt;/p&gt;

&lt;p&gt;When SSG runs, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scans your routes for &lt;strong&gt;static-exportable pages&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Generates a sitemap based on routes it finds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overwrites&lt;/strong&gt; any static &lt;code&gt;sitemap.xml&lt;/code&gt; from your &lt;code&gt;public/&lt;/code&gt; folder&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problem: &lt;strong&gt;SSG cannot find any exportable routes&lt;/strong&gt; when using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic routes (e.g., &lt;code&gt;[lang]/&lt;/code&gt;, &lt;code&gt;[id]/&lt;/code&gt;, &lt;code&gt;[slug]/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;SSR-only routes (routes without &lt;code&gt;onStaticGenerate&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Node.js adapter (designed for runtime SSR, not static export)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result: SSG generates an &lt;strong&gt;empty sitemap&lt;/strong&gt; with zero URLs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: Disable SSG and Use Static Sitemap (Recommended for SSR apps)
&lt;/h3&gt;

&lt;p&gt;This is the simplest solution when you're building a pure SSR application with the Node.js adapter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Disable SSG in Node.js Adapter
&lt;/h4&gt;

&lt;p&gt;Edit &lt;code&gt;adapters/node-server/vite.config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nodeServerAdapter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@builder.io/qwik-city/adapters/node-server/vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;extendConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@builder.io/qwik-city/vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;baseConfig&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../vite.config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;extendConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;ssr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;rollupOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/entry.express.tsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@qwik-city-plan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nf"&gt;nodeServerAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ssg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ⚠️ CRITICAL: Completely disable SSG - using static sitemap.xml&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key change:&lt;/strong&gt; &lt;code&gt;ssg: null&lt;/code&gt; completely disables the automatic sitemap generation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Create Static Sitemap
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;public/sitemap.xml&lt;/code&gt; with your routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;urlset&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.sitemaps.org/schemas/sitemap/0.9"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://yourdomain.com/&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;lastmod&amp;gt;&lt;/span&gt;2024-12-01&lt;span class="nt"&gt;&amp;lt;/lastmod&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;changefreq&amp;gt;&lt;/span&gt;weekly&lt;span class="nt"&gt;&amp;lt;/changefreq&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;priority&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/priority&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://yourdomain.com/about/&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;changefreq&amp;gt;&lt;/span&gt;monthly&lt;span class="nt"&gt;&amp;lt;/changefreq&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;priority&amp;gt;&lt;/span&gt;0.8&lt;span class="nt"&gt;&amp;lt;/priority&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Add all your static routes here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/urlset&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For multi-language sites:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;urlset&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.sitemaps.org/schemas/sitemap/0.9"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://yourdomain.com/&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;priority&amp;gt;&lt;/span&gt;1.0&lt;span class="nt"&gt;&amp;lt;/priority&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://yourdomain.com/es/&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;priority&amp;gt;&lt;/span&gt;0.8&lt;span class="nt"&gt;&amp;lt;/priority&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://yourdomain.com/de/&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;priority&amp;gt;&lt;/span&gt;0.8&lt;span class="nt"&gt;&amp;lt;/priority&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- etc --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/urlset&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Remove SSG Commands
&lt;/h4&gt;

&lt;p&gt;If your &lt;code&gt;package.json&lt;/code&gt; has &lt;code&gt;qwik city collect&lt;/code&gt;, remove it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build.production &amp;amp;&amp;amp; qwik city collect"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build.production"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Build and Verify
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build:deploy
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; dist/sitemap.xml
&lt;span class="nb"&gt;cat &lt;/span&gt;dist/sitemap.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see your sitemap content (not empty) in &lt;code&gt;dist/sitemap.xml&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 5: Verify Server Serves It
&lt;/h4&gt;

&lt;p&gt;The Node.js server will automatically serve &lt;code&gt;dist/sitemap.xml&lt;/code&gt; as a static file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node server.js
curl http://localhost:3000/sitemap.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should return your full sitemap.&lt;/p&gt;




&lt;h3&gt;
  
  
  Option 2: Use Dynamic SSR Route (For Complex/Dynamic Sitemaps)
&lt;/h3&gt;

&lt;p&gt;If your sitemap needs to be generated dynamically (e.g., from a CMS or database), create an SSR route instead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create &lt;code&gt;src/routes/sitemap.xml/index.ts&lt;/code&gt;:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RequestHandler&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@builder.io/qwik-city&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SUPPORTED_LOCALES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ru&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onGet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RequestHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Root URL&lt;/span&gt;
    &lt;span class="s2"&gt;`  &amp;lt;url&amp;gt;
    &amp;lt;loc&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&amp;lt;/loc&amp;gt;
    &amp;lt;lastmod&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;T&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/lastmod&amp;gt;
    &amp;lt;changefreq&amp;gt;weekly&amp;lt;/changefreq&amp;gt;
    &amp;lt;priority&amp;gt;1.0&amp;lt;/priority&amp;gt;
  &amp;lt;/url&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Language-specific URLs&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;SUPPORTED_LOCALES&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`  &amp;lt;url&amp;gt;
    &amp;lt;loc&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&amp;lt;/loc&amp;gt;
    &amp;lt;changefreq&amp;gt;weekly&amp;lt;/changefreq&amp;gt;
    &amp;lt;priority&amp;gt;0.8&amp;lt;/priority&amp;gt;
  &amp;lt;/url&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sitemap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;urls&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&amp;lt;/urlset&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sitemap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/xml; charset=utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache-Control&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public, max-age=86400&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Cache for 1 day&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Still disable SSG&lt;/strong&gt; in the adapter config to avoid conflicts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Happens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Qwik's SSG Behavior
&lt;/h3&gt;

&lt;p&gt;Qwik City has two deployment modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Static Site Generation (SSG)&lt;/strong&gt; - Pre-renders pages at build time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-Side Rendering (SSR)&lt;/strong&gt; - Renders pages on-demand at runtime&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;strong&gt;Node.js adapter&lt;/strong&gt; is designed for SSR, but it &lt;strong&gt;still runs SSG by default&lt;/strong&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate a sitemap&lt;/li&gt;
&lt;li&gt;Pre-render any static pages marked with &lt;code&gt;onStaticGenerate&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Problem with Dynamic Routes
&lt;/h3&gt;

&lt;p&gt;When you have routes like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/routes/[lang]/index.tsx&lt;/code&gt; (language parameter)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/routes/posts/[id]/index.tsx&lt;/code&gt; (post ID parameter)&lt;/li&gt;
&lt;li&gt;SSR-only routes without &lt;code&gt;onStaticGenerate&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SSG cannot know which parameter values to use&lt;/strong&gt; unless you explicitly define them with &lt;code&gt;onStaticGenerate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onStaticGenerate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StaticGenerateHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;es&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="c1"&gt;// etc&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;But even with &lt;code&gt;onStaticGenerate&lt;/code&gt;&lt;/strong&gt;, if you're using the Node.js adapter for pure SSR, the SSG step may not recognize these routes because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The adapter is optimized for runtime rendering&lt;/li&gt;
&lt;li&gt;The route manifest may be incomplete at build time&lt;/li&gt;
&lt;li&gt;Environment variables (like &lt;code&gt;ORIGIN&lt;/code&gt;) may be missing during build&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why It Works Locally
&lt;/h3&gt;

&lt;p&gt;In development (&lt;code&gt;npm run dev&lt;/code&gt;):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vite serves files directly from &lt;code&gt;public/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No SSG runs&lt;/li&gt;
&lt;li&gt;Your static &lt;code&gt;sitemap.xml&lt;/code&gt; is served as-is&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSG runs during build&lt;/li&gt;
&lt;li&gt;Finds 0 exportable routes&lt;/li&gt;
&lt;li&gt;Generates empty sitemap&lt;/li&gt;
&lt;li&gt;Overwrites your static file&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ Using &lt;code&gt;exclude: ['*']&lt;/code&gt; instead of &lt;code&gt;ssg: null&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This does NOT fully disable SSG:&lt;/span&gt;
&lt;span class="nf"&gt;nodeServerAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ssg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSG still runs and generates an empty sitemap. Use &lt;code&gt;ssg: null&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Keeping &lt;code&gt;qwik city collect&lt;/code&gt; in build script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build.production &amp;amp;&amp;amp; qwik city collect"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This explicitly runs SSG and will overwrite your static sitemap. Remove it.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Putting sitemap in &lt;code&gt;dist/&lt;/code&gt; manually
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;dist/&lt;/code&gt; folder is cleared on every build. Always put the static sitemap in &lt;code&gt;public/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Creating both static sitemap AND SSR route
&lt;/h3&gt;

&lt;p&gt;Pick one approach. If you have both &lt;code&gt;public/sitemap.xml&lt;/code&gt; AND &lt;code&gt;src/routes/sitemap.xml/&lt;/code&gt;, the SSR route takes precedence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification Checklist
&lt;/h2&gt;

&lt;p&gt;After implementing the fix:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Build completes without "Starting Qwik City SSG..." message (if using &lt;code&gt;ssg: null&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;dist/sitemap.xml&lt;/code&gt; exists and is &lt;strong&gt;not&lt;/strong&gt; 109 bytes (empty sitemap size)&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;cat dist/sitemap.xml&lt;/code&gt; shows your actual URLs&lt;/li&gt;
&lt;li&gt;[ ] Production server serves sitemap: &lt;code&gt;curl https://yourdomain.com/sitemap.xml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Sitemap contains expected number of URLs&lt;/li&gt;
&lt;li&gt;[ ] No errors in build logs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Additional Notes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Trailing Slash Issue
&lt;/h3&gt;

&lt;p&gt;If &lt;code&gt;/sitemap.xml/&lt;/code&gt; (with trailing slash) doesn't redirect to &lt;code&gt;/sitemap.xml&lt;/code&gt;, this is a Qwik City routing behavior. It's harmless - search engines will normalize the URL.&lt;/p&gt;

&lt;p&gt;To enforce redirect, you can add this to your &lt;code&gt;server.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Redirect /sitemap.xml/ to /sitemap.xml&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/sitemap.xml/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;301&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/sitemap.xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ... rest of server code&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to Use Each Approach
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use Static Sitemap (&lt;code&gt;ssg: null&lt;/code&gt; + &lt;code&gt;public/sitemap.xml&lt;/code&gt;)&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Pure SSR application&lt;/li&gt;
&lt;li&gt;✅ Routes are known at development time&lt;/li&gt;
&lt;li&gt;✅ Sitemap doesn't change often&lt;/li&gt;
&lt;li&gt;✅ Simple deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use SSR Route (&lt;code&gt;src/routes/sitemap.xml/index.ts&lt;/code&gt;)&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Content comes from CMS/database&lt;/li&gt;
&lt;li&gt;✅ Routes are dynamic&lt;/li&gt;
&lt;li&gt;✅ Sitemap needs real-time updates&lt;/li&gt;
&lt;li&gt;✅ Need to include user-generated content&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Related Issues
&lt;/h2&gt;

&lt;p&gt;This fix also resolves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Sitemap is empty on Vercel/Netlify/production"&lt;/li&gt;
&lt;li&gt;"qwik city collect generates no pages"&lt;/li&gt;
&lt;li&gt;"SSG finds 0 routes in Node.js adapter"&lt;/li&gt;
&lt;li&gt;"public/sitemap.xml not copied to dist"&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;This solution was discovered after extensive debugging of Qwik v1.17.x with Node.js adapter on production deployments where local builds worked but production sitemaps were empty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; The Node.js adapter runs SSG by default even for SSR apps, and an empty route manifest causes it to generate an empty sitemap that overwrites static files.&lt;/p&gt;




&lt;h2&gt;
  
  
  Need Help?
&lt;/h2&gt;

&lt;p&gt;If your sitemap is still empty after this fix:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Check &lt;code&gt;dist/sitemap.xml&lt;/code&gt; size: &lt;code&gt;ls -lh dist/sitemap.xml&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;109 bytes = empty sitemap (SSG still running)&lt;/li&gt;
&lt;li&gt;1-2 KB+ = static sitemap copied successfully&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check build logs for "Starting Qwik City SSG"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If present, SSG is still enabled&lt;/li&gt;
&lt;li&gt;Should not appear when &lt;code&gt;ssg: null&lt;/code&gt; is set&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify &lt;code&gt;public/sitemap.xml&lt;/code&gt; exists in your repository&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not ignored by &lt;code&gt;.gitignore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Committed to version control&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check production build includes &lt;code&gt;public/&lt;/code&gt; folder&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CI/CD pipeline copies all files&lt;/li&gt;
&lt;li&gt;No build steps delete &lt;code&gt;public/&lt;/code&gt; assets&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>help</category>
      <category>webdev</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>4chan .mp4 file standards</title>
      <dc:creator>developer</dc:creator>
      <pubDate>Sun, 17 Aug 2025 20:06:24 +0000</pubDate>
      <link>https://dev.to/_dj_/4chan-mp4-file-standards-3de2</link>
      <guid>https://dev.to/_dj_/4chan-mp4-file-standards-3de2</guid>
      <description>&lt;p&gt;Not all mp4 standards can be uploaded on 4chan imageboards. This is tested:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8k47qtuafqogsjrlf0o0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8k47qtuafqogsjrlf0o0.png" alt=" " width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Properties:&lt;br&gt;
Max duration: 120 seconds&lt;/p&gt;

&lt;p&gt;Container:&lt;br&gt;
Format: MP4 (MPEG-4 Part 14)&lt;br&gt;
Major Brand: isom&lt;br&gt;
Compatible Brands: isom, iso2, avc1, mp41&lt;br&gt;
File Extension: .mp4&lt;br&gt;
Streaming Compatibility: "Fast Start" enabled&lt;br&gt;
Video Track:&lt;br&gt;
Codec: H.264 (AVC)&lt;br&gt;
Handler Description: VideoHandler&lt;br&gt;
Pixel Format: yuv420p&lt;br&gt;
Color Range: Limited (tv)&lt;br&gt;
Color Primaries: BT.709&lt;br&gt;
Transfer Characteristics: BT.709&lt;br&gt;
Matrix Coefficients: BT.709&lt;br&gt;
Bit Depth: 8-bit per channel&lt;br&gt;
Resolution: Tier-based (e.g., 720p, 480p, etc.)&lt;br&gt;
Frame Rate: Tier-based (e.g., original FPS or 30 FPS)&lt;br&gt;
Bitrate: Variable (calculated to meet file size target)&lt;br&gt;
Audio Track (Separate File):&lt;br&gt;
Codec: AAC (Advanced Audio Coding)&lt;br&gt;
Handler Description: SoundHandler&lt;br&gt;
Bitrate: 128 kbps&lt;/p&gt;

&lt;p&gt;(-an to remove audio)&lt;/p&gt;

&lt;p&gt;FFmpeg Commands:&lt;br&gt;
Video-only MP4 (Re-encoded):&lt;br&gt;
&lt;code&gt;ffmpeg -y -i input.ext -an -c:v libx264 -b:v 1500k -maxrate 1500k -bufsize 3000k -vf "scale=-2:480,fps=30" -pix_fmt yuv420p -color_range tv -colorspace bt709 -color_primaries bt709 -color_trc bt709 -metadata handler_name="VideoHandler" -movflags +faststart output.mp4&lt;/code&gt;&lt;br&gt;
Video-only MP4 (Stream Copy):&lt;br&gt;
&lt;code&gt;ffmpeg -y -i input.ext -an -c:v copy -metadata handler_name="VideoHandler" -movflags +faststart output.mp4&lt;/code&gt;&lt;br&gt;
Audio-only AAC:&lt;br&gt;
&lt;code&gt;ffmpeg -y -i input.ext -vn -c:a aac -b:a 128k -metadata handler_name="SoundHandler" output.aac&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fix MEGA many folders in Windows Explorer Navigation Pane</title>
      <dc:creator>developer</dc:creator>
      <pubDate>Sun, 13 Jul 2025 03:03:20 +0000</pubDate>
      <link>https://dev.to/_dj_/fix-mega-many-folders-in-windows-explorer-navigation-pane-417a</link>
      <guid>https://dev.to/_dj_/fix-mega-many-folders-in-windows-explorer-navigation-pane-417a</guid>
      <description>&lt;p&gt;Sometimes MEGA Desktop Sync reinstalls and adds another file explorer shortcut. After a few reinstalls it starts to look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97h6i0papols64yahxzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97h6i0papols64yahxzk.png" alt=" " width="268" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MEGA support did not have an answer for why the software does this, but to fix:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk03gpzwa345ygm8l1ocz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk03gpzwa345ygm8l1ocz.png" alt=" " width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uncheck and then check this box "Enable File Explorer Integration" to disable then re-enable the Mega File Explorer shortcuts.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>windows</category>
      <category>howto</category>
    </item>
    <item>
      <title>Connecting to IRC with Halloy</title>
      <dc:creator>developer</dc:creator>
      <pubDate>Thu, 30 May 2024 01:15:03 +0000</pubDate>
      <link>https://dev.to/_dj_/connecting-to-irc-with-halloy-5i8</link>
      <guid>https://dev.to/_dj_/connecting-to-irc-with-halloy-5i8</guid>
      <description>&lt;p&gt;Halloy is a new IRC client written in Rust that is fast with good theming. Here is how I set up a connection to an irc channel with Halloy and here is how to config Halloy for Rizon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0dhckr5nk3dy5br12ta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0dhckr5nk3dy5br12ta.png" alt=" " width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After &lt;a href="https://github.com/squidowl/halloy/releases" rel="noopener noreferrer"&gt;downloading Halloy&lt;/a&gt;, I referred to the &lt;a href="https://halloy.squidowl.org/index.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Halloy uses a config.toml file, easily edited in code editor like VSCode. By default this is next to the Halloy installation, for me, in AppData/Roaming on Windows.&lt;/p&gt;

&lt;p&gt;Halloy has command bar on the bottom left of the application window, and opening that gives options including "Configuration: Open config directory".&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic connection to Rizon
&lt;/h3&gt;

&lt;p&gt;In config.toml, Halloy already gives an example setup. For Rizon network, here's another example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[servers.rizon]&lt;br&gt;
nickname = "YourNicknameHere"&lt;br&gt;
nick_password = "yourPassword"&lt;br&gt;
server = "irc.rizon.net"&lt;br&gt;
channels = ["#chat"]&lt;br&gt;
port = 6697&lt;br&gt;
on_connect = ["/msg NickServ IDENTIFY your_password"]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When Halloy opens, the name of the window will be what is written after the period in [servers.name]. Nickname is for irc, password, if needed, is used for authenticating. The server is Rizon, and the channel list &lt;code&gt;["#chat", "#example"]&lt;/code&gt; is for connecting to the channel after opening Halloy. Port 6697 is for ssl with Rizon.&lt;br&gt;
The on_connect is for specifying irc commands to run on connection. Here I have a message to NickServ asking to identify a username with a password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring Halloy with IRC Bouncer
&lt;/h3&gt;

&lt;p&gt;Halloy also works with irc bouncers. Here is an example in config.toml file, and because my username on irc bouncer is different from nickname on irc...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[servers.bnc]&lt;br&gt;
nickname = "MyNickName"&lt;br&gt;
username = "MyBouncerUsername"&lt;br&gt;
password = "bouncer_server_password_here"&lt;br&gt;
server = "chat.Yourbouncerserverhere.com"&lt;br&gt;
port = +1234&lt;br&gt;
use_tls = true&lt;br&gt;
on_connect = ["nick MyNickName", "/msg NickServ IDENTIFY myNickServPassword", "/join #example"]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The plus on the port (which should be the port number you have to connect to the irc bouncer) indicates ssl.&lt;br&gt;
After logging on to the irc bouncer server, I use the on_connect command to change to preferred nickname, verify with the Nickname Service, and join the preferred channel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Themes
&lt;/h3&gt;

&lt;p&gt;To install a theme, &lt;a href="https://themes.halloy.chat/" rel="noopener noreferrer"&gt;download&lt;/a&gt; and place the theme file in the themes folder where Halloy is installed. Open Halloy's command bar (keyboard shortcut: ctrl+k) and then type "theme", select one of the "Switch to theme" options.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
