Public: anyone can read this; the crew can change it.
A property page link pasted into a text or a post previews the home: its address, price, facts and hero photo #91
Check · Review · Land · Live done — Landed and live in production.
A link to `/homes/:id` now previews the home itself: its address, price, facts and hero photo. The tests I ran pass: property, hostile, offmarket, security, a11y, design, deps, walkthrough and speed. `bun x tsc --noEmit` printed only tsc's help text because the repo has no `tsconfig.json`, so it didn't type-check. The repo has no `scripts/gate.ts` or `scripts/fast.ts`, and I did not run the full s…
shipped production is serving it deploy 957b843
A link to /homes/:id now previews the home itself: its address, price, facts and hero photo. The tests I ran pass: property, hostile, offmarket, security, a11y, design, deps, walkthrough and speed. bun x tsc --noEmit printed only tsc's help text because the repo has no tsconfig.json, so it didn't type-check. The repo has no scripts/gate.ts or scripts/fast.ts, and I did not run the full suite. I did not try the app against a real iMessage, Facebook or LinkedIn card.
What changed
src/pages/layout.ts:Frametakes an optionaldescription,image(absolute URL plus alt text) andshareTitle. Pages that pass none keep today's tags exactly. With an image, it addsog:image,og:image:altandtwitter:image, andtwitter:cardbecomessummary_large_image. The CSP and the other security headers are untouched.src/pages/property.ts:
- og:title and twitter:title are "address · price".
- The meta, og: and twitter: descriptions are the facts line plus the first sentence of the approved MLS words. An unapproved draft contributes nothing, and og:type stays website.
- The image is the hero photo on the public origin, with that photo's description as alt text. A listing with no photo gets no image tags.
- A withdrawn or expired listing's title is the address alone and its description is "This home is no longer available." It has no price and no facts.
- Tests:
- src/property.test.ts: the tags for the sample listing with a hero photo, no draft words in the tags, no image tags without a photo, and the off-market preview.
- src/hostile.test.ts: /homes/:id is added to the meta-escaping check, plus a test that the hostile address stays inert inside the title and description attributes.
README.md: a note that the sample photos are SVG, which some networks ignore on a card, so those previews show text only. I did not convert images or add a dependency.
Things to look at
- The facts line in the description is the app's existing
factsLine, so it also carries lot and year ("3 bd · 2.5 ba · 2,140 sq ft · 0.18 acre lot · built 1928"), not just the three facts in the issue's example. - No role in the permission table was loosened.
Preview checked at this head: /homes/1 carries the address and price in og:title and twitter:title, the facts line plus first approved sentence in the descriptions, an absolute og:image and twitter:image on the public origin with alt text, and twitter:card summary_large_image. Pages with no description or image keep their tags. Output is escaped, and the hostile-address test covers it. No contract cell changed. Minor: the description carries lot and year as well as the three facts, and the SVG sample photos are ignored by some networks (the README says so).
A link to
/homes/:idnow previews the home itself: its address, price, facts and hero photo. The tests I ran pass: property, hostile, offmarket, security, a11y, design, deps, walkthrough and speed.bun x tsc --noEmitprinted only tsc's help text because the repo has notsconfig.json, so it didn't type-check. The repo has noscripts/gate.tsorscripts/fast.ts, and I did not run the full suite. I did not try the app against a real iMessage, Facebook or LinkedIn card.What changed
src/pages/layout.ts:Frametakes an optionaldescription,image(absolute URL plus alt text) andshareTitle. Pages that pass none keep today's tags exactly. With an image, it addsog:image,og:image:altandtwitter:image, andtwitter:cardbecomessummary_large_image. The CSP and the other security headers are untouched.src/pages/property.ts:-
og:titleandtwitter:titleare "address · price". - The meta,og:andtwitter:descriptions are the facts line plus the first sentence of the approved MLS words. An unapproved draft contributes nothing, andog:typestayswebsite. - The image is the hero photo on the public origin, with that photo's description as alt text. A listing with no photo gets no image tags. - A withdrawn or expired listing's title is the address alone and its description is "This home is no longer available." It has no price and no facts.-
src/property.test.ts: the tags for the sample listing with a hero photo, no draft words in the tags, no image tags without a photo, and the off-market preview. -src/hostile.test.ts:/homes/:idis added to the meta-escaping check, plus a test that the hostile address stays inert inside the title and description attributes.README.md: a note that the sample photos are SVG, which some networks ignore on a card, so those previews show text only. I did not convert images or add a dependency.Things to look at
factsLine, so it also carries lot and year ("3 bd · 2.5 ba · 2,140 sq ft · 0.18 acre lot · built 1928"), not just the three facts in the issue's example.Closes #84