← 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 →