[object Object]

← back to Quadrille House Site

Add search and AI discovery endpoints

6c6b2d8c79c086d21f8c06b91b38b8699b5b52db · 2026-08-31 02:08:00 -0700 · Steve Abrams

Files touched

Diff

commit 6c6b2d8c79c086d21f8c06b91b38b8699b5b52db
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 31 02:08:00 2026 -0700

    Add search and AI discovery endpoints
---
 server.js | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/server.js b/server.js
index ebe43f5..fc64d2e 100644
--- a/server.js
+++ b/server.js
@@ -16,6 +16,7 @@ const path = require('path');
 const PORT = process.env.PORT || 9943;
 const DATA = path.join(__dirname, 'data');
 const STORE_BASE = 'https://www.designerwallcoverings.com';
+const PUBLIC_BASE = 'https://quadrille.designerwallcoverings.com';
 
 let HOUSE = { products: [], brands: [] };
 let LOOKBOOK = { lookbooks: [], rooms: [] };
@@ -128,6 +129,24 @@ app.get('/api/facets', (req, res) => {
 
 app.get('/api/lookbook', (_req, res) => res.json(LOOKBOOK));
 
+// Search/answer-engine discovery. Keep the sitemap limited to pages this app
+// actually owns; live China Seas PDPs canonicalize to Designer Wallcoverings.
+app.get('/robots.txt', (_req, res) => {
+  res.type('text/plain').send(`User-agent: *\nAllow: /\nSitemap: ${PUBLIC_BASE}/sitemap.xml\n`);
+});
+
+app.get('/sitemap.xml', (_req, res) => {
+  const urls = [PUBLIC_BASE, ...HOUSE.products
+    .filter(p => p.handle && !p.store_url)
+    .map(p => `${PUBLIC_BASE}/product/${encodeURIComponent(p.handle)}`)];
+  const body = urls.map(url => `  <url><loc>${url.replace(/&/g, '&amp;')}</loc></url>`).join('\n');
+  res.type('application/xml').send(`<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${body}\n</urlset>\n`);
+});
+
+app.get('/llms.txt', (_req, res) => {
+  res.type('text/plain').send(`# The Quadrille House\n\n> A Designer Wallcoverings editorial catalog of Quadrille-family hand-screened wallcoverings and fabrics.\n\n- Canonical site: ${PUBLIC_BASE}/\n- Main store: ${STORE_BASE}/\n- Catalog API: ${PUBLIC_BASE}/api/products\n- Brand and color facets: ${PUBLIC_BASE}/api/facets\n- Lookbooks: ${PUBLIC_BASE}/api/lookbook\n\nProducts linked to ${STORE_BASE} are canonical there. Quote-only catalog pages are canonical to this site.\n`);
+});
+
 // Memo-sample / quote request (to-the-trade, NO public price) for HELD brands.
 // Local stub: logs the request. (Real send is gated through vp-compliance-policy.)
 app.post('/api/quote', (req, res) => {

← 3ea5258 viewer standard: add Grid/List toggle + per-field on/off men  ·  back to Quadrille House Site  ·  deploy: guard prod-only runtime data from rsync --delete 45e0a40 →