[object Object]

← back to Wallco Ai

wallco.ai · Last-Modified + If-Modified-Since on /designs and /design/:id — Conditional GET: crawlers (Googlebot/Bingbot) get 304 (0 bytes) on repeat visits when no design newer than their last crawl. CATALOG_LAST_MODIFIED computed once at loadDesigns() from max(design.created_at); per-design page uses design.created_at. maybe304() helper floors to 1-second precision (HTTP-date drops millis). Verified: matching IMS → 304 0B, stale IMS → 200 94KB.

b74701c70b9003feeb878a4842b87e04f724a1ac · 2026-05-12 07:25:56 -0700 · SteveStudio2

Files touched

Diff

commit b74701c70b9003feeb878a4842b87e04f724a1ac
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Tue May 12 07:25:56 2026 -0700

    wallco.ai · Last-Modified + If-Modified-Since on /designs and /design/:id — Conditional GET: crawlers (Googlebot/Bingbot) get 304 (0 bytes) on repeat visits when no design newer than their last crawl. CATALOG_LAST_MODIFIED computed once at loadDesigns() from max(design.created_at); per-design page uses design.created_at. maybe304() helper floors to 1-second precision (HTTP-date drops millis). Verified: matching IMS → 304 0B, stale IMS → 200 94KB.
---
 server.js | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/server.js b/server.js
index f3fec21..ecb9da1 100644
--- a/server.js
+++ b/server.js
@@ -169,9 +169,17 @@ app.get('/sitemap.xml', (req, res) => {
 
 // ── Load design catalog (snapshot from DB — never stale-live Shopify)
 let DESIGNS = [];
+let CATALOG_LAST_MODIFIED = new Date();  // freshest design.created_at across the catalog
 function loadDesigns() {
   try {
     DESIGNS = JSON.parse(fs.readFileSync(DATA_FILE, 'utf8'));
+    // Track max created_at so /designs etc. can emit a useful Last-Modified.
+    let max = 0;
+    for (const d of DESIGNS) {
+      const t = Date.parse(d.created_at || '');
+      if (t && t > max) max = t;
+    }
+    CATALOG_LAST_MODIFIED = max ? new Date(max) : new Date();
   } catch (e) {
     console.error('Failed to load designs.json:', e.message);
     DESIGNS = [];
@@ -179,6 +187,26 @@ function loadDesigns() {
 }
 loadDesigns();
 
+// Conditional-GET helper: if If-Modified-Since header matches our lastmod (1-second
+// precision since HTTP-date drops millis), emit 304 with empty body. Crawlers like
+// Googlebot/Bingbot use this to skip full-body downloads on repeat visits.
+// Returns true if a 304 was sent (caller should bail). HEAD requests handled too.
+function maybe304(req, res, lastModifiedDate) {
+  if (!lastModifiedDate || isNaN(lastModifiedDate.getTime())) return false;
+  // HTTP-date truncates to 1s; floor both sides to match.
+  const lastMs = Math.floor(lastModifiedDate.getTime() / 1000) * 1000;
+  res.setHeader('Last-Modified', new Date(lastMs).toUTCString());
+  const ims = req.headers['if-modified-since'];
+  if (ims) {
+    const imsMs = Date.parse(ims);
+    if (!isNaN(imsMs) && imsMs >= lastMs) {
+      res.status(304).end();
+      return true;
+    }
+  }
+  return false;
+}
+
 // ── Color sort helpers
 function hexToHSL(hex) {
   if (!hex) return [0, 0, 0.5];
@@ -910,6 +938,10 @@ ${HAMBURGER_JS}
 
 // ── DESIGNS CATALOG (full grid with sort + density + category filter)
 app.get('/designs', (req, res) => {
+  // Conditional GET: emit Last-Modified from the freshest design in the
+  // in-memory catalog. Crawlers issuing If-Modified-Since get a 304 when
+  // no new design has landed since their last crawl.
+  if (maybe304(req, res, CATALOG_LAST_MODIFIED)) return;
   const sort = req.query.sort || 'newest';
   const cat  = req.query.cat  || '';
   const q    = (req.query.q   || '').toLowerCase().trim();
@@ -2534,6 +2566,11 @@ app.get('/design/:id', (req, res) => {
   }
   if (!design) return res.status(404).type('html').send(renderDesignNotFound(req, id));
 
+  // Conditional GET on per-design created_at. Designs rarely mutate after
+  // creation — admin room-mockup generations bump CATALOG_LAST_MODIFIED but
+  // the per-design page itself reflects design.created_at for crawler caching.
+  if (design.created_at && maybe304(req, res, new Date(design.created_at))) return;
+
   const relIdx = DESIGNS.findIndex(d => d.id === id);
   const prev = relIdx > 0 ? DESIGNS[relIdx-1] : null;
   const next = relIdx < DESIGNS.length-1 ? DESIGNS[relIdx+1] : null;

← 324afdd security — prompt-injection hardening on Ollama chat path. A  ·  back to Wallco Ai  ·  wallco.ai · Last-Modified + 304 on /sitemap.xml + /robots.tx 8d04faa →