Launch Checklists for Brand Sites: DNS to Analytics Without Drama
Tick DNS, SSL, redirects, analytics, forms, 404, and OG on the live production domain before you announce — named owners, named rollback, no Friday 6pm heroics.
William Spurlock Founder — Spurlock Studios Updated 21 MIN
Launches fail less from bad design than from skipped boring steps: wrong DNS TTL, www vs apex loops, analytics in the staging property, forms posting to nowhere, a missing OG image, staging noindex still on production, a client tweeting a URL that 404s. A website launch checklist is operational craft. Treat go-live like a scene change with a call sheet — then tick DNS, analytics, forms, 404, and Open Graph on the production hostname, not on a preview. This spoke sits under Websites That Feel Like Films.
The short answer
- Freeze copy, approve the redirect map, confirm who can edit DNS, and name a rollback before cutover week.
- Point apex and www at one canonical home. Leave MX, SPF, and DKIM alone unless you are migrating mail.
- Put the production GA4 measurement ID on the live domain. Submit a real form. Hit a nonsense URL and confirm a branded 404. Debug the home OG image.
- Soft-launch when a campaign is attached. Hard-launch only when the blast and the domain flip are the same planned hour.
- If the client cannot find the registrar two days out, the date moves. Guessing DNS is not a launch strategy.
What belongs on a website launch checklist?
The list is a call sheet, not a vibe. Every brand site I ship — and I have shipped hundreds — gets some version of this table. Cut rows that do not apply. Do not skip the ones that do.
| System | Done looks like | Failure if skipped |
|---|---|---|
| DNS | Apex + www resolve to the same host; email records untouched | Hours of “it still shows the old site” plus a dead inbox |
| HTTPS | Clean cert on both hostnames; HTTP redirects to HTTPS | Browser warnings on the announcement URL |
| Redirects | Top legacy URLs 301 to live equivalents | Paid and bookmarked traffic 404s on day one |
| Analytics | Production G- ID firing; one test event visible | Blind first week; you cannot prove the launch |
| Forms | Test lead arrives; notification email lands | The only conversion path is a black hole |
| 404 | Branded page, real 404 status, path home | Dead links look like an unfinished site |
| Open Graph | Home + share targets show the intended image | The campaign posts a cropped logo or a blank card |
| robots / sitemap | Production crawlable; staging blocked or passworded | Staging indexed, or money pages noindex |
| Rollback | One sentence: revert DNS, prior deploy, or maintenance page | Nobody knows what “undo” means at 11pm |
Pre-launch freeze (T-72 to T-24):
- Content freeze window agreed in writing
- Final pass on fold, contact, pricing, legal
- Redirect map approved (old → new)
- DNS access confirmed — who has the login, who can change records
- SSL strategy named (platform-managed vs custom)
- Legacy site backup or export if this replaces a live site
- Rollback named out loud in the project channel
If a box has no owner, it is not on the checklist. It is a wish.
Who owns each item on a website launch checklist?
Launches go sideways when everyone can edit DNS and no one wrote the redirect map. Name owners before cutover week.
| Role | Owns | Must not “help” by |
|---|---|---|
| Studio lead | Freeze, go/no-go, client comms | Editing DNS from memory |
| Implementer | Deploy, redirects, forms, tags, 404, OG | Publishing a draft tag container |
| Client | Registrar, copy approvals, legal pages, analytics login | Tweeting the URL before QA on production |
| Marketing | Campaign timing, UTM plan, announcement copy | Pasting a staging URL into the blast |
Who holds the registrar, host, and CMS after the sprint is a different question from who ticks boxes on cutover day. Settle both in writing. Who owns your website when you leave is the ownership contract; this post is the launch call sheet.
Access hygiene the week of launch:
- 2FA on registrar, DNS, host, CMS, and analytics
- Contractor logins that are done, removed
- Credentials that traveled over Slack or text, rotated
- Production env vars checked — no staging API keys, no debug flags
Launch week is a popular time for account takeovers because people share passwords under time pressure. A compromised brand site becomes an anti-case-study overnight.
What DNS records should you touch on a website launch?
Drama usually means: wrong account, expired registrar login, a www CNAME fighting the apex, or email dying because someone deleted MX records while “just updating the website.” Write the exact records you will change. Screenshot before. Change only those rows.
| Record | Typical job | Touch on a site launch? |
|---|---|---|
| A / AAAA / ALIAS / ANAME | Apex → host | Yes, if the host changes |
| CNAME | www → host or apex | Yes — pick one canonical |
| MX | Inbound mail | No, unless you are migrating mail |
| TXT (SPF) | Who may send mail | No, unless senders change |
| TXT (DKIM / DMARC) | Mail auth | No, unless you are rotating keys |
| TXT (verification) | Search Console / vendor proof | Yes, if you still need ownership |
Google Workspace inbound mail still depends on MX pointing at Google’s mail hosts — as of their current setup docs, that is smtp.google.com at the apex (Set up MX records for Google Workspace). SPF is a separate TXT record; if the domain sends only through Google Workspace, their documented value is v=spf1 include:_spf.google.com ~all (Set up SPF). Deleting either while you “point the website” is how a launch becomes an outage.
TTL is the cache clock. Cloudflare’s docs are blunt: longer TTLs make lookups faster and make updates slower. Proxied records sit on Auto at 300 seconds and you cannot edit that. DNS-only records can be set between 60 seconds (30 on Enterprise) and one day (Time to Live (TTL)). Their FAQ says the same operational rule I use: if you expect to change a record with a large TTL, reduce the TTL ahead of time so the cutover can take effect (Cloudflare DNS FAQ).
DNS procedure I actually run:
- Confirm the account (registrar vs DNS host — they are often different).
- Export or screenshot every record.
- Lower TTL on the records you will change, at least one full old-TTL window before cutover.
- Write the new records in the project doc. Do not improvise in the panel.
- After the site is stable, raise TTL again so you are not paying extra lookups forever.
If the client cannot find DNS access two days before launch, the launch date moves. Do not heroically guess.
What HTTPS checks belong on a website launch checklist?
A lock icon on staging means nothing. Certificates have to issue on the public hostnames after DNS flips. Platform-managed certs (Netlify, Cloudflare, Webflow) usually provision in minutes; they still fail when the apex and www are split across two hosts, or when CAA records block the issuer.
| Check | Pass | Fail |
|---|---|---|
| Apex HTTPS | https://example.com loads with a valid cert | Cert name mismatch or timeout |
| www HTTPS | https://www.example.com matches the same site | www still on the old host |
| HTTP → HTTPS | http:// 301/308s to https:// | Both protocols serve different content |
| Mixed content | No http:// assets on HTTPS pages | Images or scripts blocked; “not fully secure” |
Mixed content is an HTTPS page that still fetches HTTP assets. Browsers auto-upgrade some image/audio/video requests and block the rest — scripts especially (Mixed content — MDN). A brand site that “looks fine on my laptop” can lose its typeface or a form script on someone else’s browser. Scan the production HTML for leftover http:// after the cert is live.
HTTPS checklist:
- Certificate clean on apex and www
- HTTP redirects to HTTPS on both
- One canonical hostname; the other redirects
- Mixed-content scan on home, contact, and one interior
- Security headers appropriate to the stack — do not paste a random blog’s CSP and hope
Do not copy a header pack from a tutorial you have not tested. A broken CSP that blocks your own form script is a quieter way to fail than a missing cert.
Should analytics use production IDs at go-live?
“We’ll add analytics next week” means you accept a blind launch. Prefer production tags at go-live with one test event you can see.
A GA4 web stream uses a measurement ID in the form G- plus letters and numbers. That ID is the link between the site and the property (GA4 Measurement ID). Installing the Google tag is a separate step from having an account — the snippet or CMS field has to carry the production ID (Set up Analytics for a website).
| Environment | Measurement ID | Consent | Events |
|---|---|---|---|
| Staging / preview | Staging property, or none | Can be looser | Optional |
| Production | Live G- ID only | Real region assumptions | Form submit, primary CTA, optional chat |
Analytics checklist on the production hostname:
- Production
G-ID in the live HTML (view source, do not trust the CMS field alone) - Tag manager container published — a draft container helps no one
- Consent banner behaves in a private window
- One test event visible in realtime or DebugView
- Staging IDs absent from production
- UTM plan matches the announcement links
I have watched teams celebrate a deploy while the live site still sent hits to a sandbox property. The campaign looked like a flop. The tags were the flop.
How do you test website forms on the production domain?
A form that works on staging and dies on production is the most expensive silent failure on a brand site. The path is the product. Test it on the live domain with a unique string you can search for in the inbox and the CRM.
On Netlify, built-in forms are not magic you get for free: you enable form detection, then mark the HTML form with data-netlify="true" or a netlify attribute so the build can register it (Forms setup). Serverless or CRM posts have the same rule in different clothes — the production endpoint and the production API key have to be the ones in the live env.
Form procedure:
- Submit from the production URL, not the preview.
- Use a unique test string (
launch-qa-2026-08-16-will). - Confirm the notification email arrives (and is not in spam).
- Confirm the row in Netlify, the CRM, or the sheet.
- Confirm spam protection does not block a normal human.
- Delete the test lead.
- Fire the analytics event for that submit.
| Stack | What you verify | Common miss |
|---|---|---|
| Netlify Forms | Detection on; attribute present; notification email | Form added in JS only, never in the static HTML the build sees |
| Serverless / Worker | Production secret, CORS, success UI | Staging secret still in the live env |
| Third-party embed | Domain allowlisted | Embed allowed on *.netlify.app, not the custom domain |
| CRM / automation | Test lead created, then deleted | Duplicate leads, or the zap still pointed at a dummy book |
If the site has a file upload, verify size limits on production. If a members area exists, verify private routes are actually private. Forms that expose an internal inbox in client-side code are a gift to scrapers — keep the address on the server.
How should 404s, 410s, and redirects work at launch?
A 404 is not a design flourish. It is an HTTP status: the server cannot find the resource (404 Not Found — MDN). Your branded “page not found” still has to return 404, not 200 with sad copy. Search engines and uptime checks care about the status. Humans care about a path home.
If a URL is gone for good, prefer 410 Gone. Google’s crawl-budget guidance treats 404 or 410 as a strong signal not to keep recrawling a dead URL; a robots.txt block keeps the URL in the queue longer (Crawl budget management).
Redirect map — build it from evidence, not memory:
- Export top landing pages from the last twelve months of the old site.
- Crawl the old site for indexable URLs.
- Include vanity paths the client printed on merch or email footers.
- Decide: 301 to a true equivalent, 410 if it should die, or a useful 404.
- Keep trailing-slash policy consistent. Do not 301
/workto/work/and back.
| Incoming | Action | Status |
|---|---|---|
| Old money page with a new equivalent | Redirect to the new URL | 301 |
| Old blog slug you kept | Keep the slug or 301 to the new slug | 301 |
| Promo URL that is finished | Say it is gone | 410 |
| Typo / junk | Branded not-found | 404 |
| Apex vs www, HTTP vs HTTPS | One hop to the canonical home | 301 / 308 |
404 checklist on production:
- Nonsense URL returns status
404(check response headers, not just the design) - Page is on-brand and offers a path home, search, or contact
- 404 and 500 templates do not pull megabytes of hero film
- Top legacy URLs from the map do not 404
- Trailing-slash policy matches the sitemap
If you skipped the redirect map, you are planning to donate equity to the void.
How do you check Open Graph before you announce a site?
The announcement is part of the launch. If marketing pastes the URL and the card is a cropped logo, you launched a shrug.
The Open Graph protocol requires four properties on a page: og:title, og:type, og:image, and og:url (The Open Graph protocol). Facebook’s image guidance is specific: use at least 1200 × 630 for high-resolution shares, 600 × 315 as the floor for a large image, and stay under 8 MB. Cache is keyed on the image URL — change the file, change the URL (Images in link shares). Width and height tags help the first share render without a blank slot.
| Tag | What I put | Launch check |
|---|---|---|
og:title | Page title, not a keyword dump | Matches the page a human would name |
og:description | One sentence the campaign can live with | Not leftover lorem |
og:image | 1200 × 630, HTTPS, unique URL | Debugger shows this image |
og:url | Canonical production URL | Not a preview hostname |
og:image:alt | What is in the image | Present if og:image is present |
OG checklist:
- Home, plus every URL in the announcement, has a dedicated image
- Image is reachable over HTTPS (no mixed-content card)
- Run the production URL through a share debugger after DNS is live
- First-share blank card: recrawl, or change the image URL
- Twitter/X tags present if that channel is in the blast — do not assume OG alone fills every network
I tick OG on the production domain the same hour I tick forms. A staging card that looks perfect will still show the wrong host in og:url if you never re-debug live.
How should robots.txt and noindex differ on production?
Staging should be noindex, preferably passworded, and should not share production analytics IDs. Production should not still point at staging CMS datasets. Environment variables are part of the checklist: one wrong API key and forms fail quietly. One leftover noindex and the new site never shows up.
A robots.txt file tells compliant crawlers which URLs they may fetch. It is not how you keep a page out of Google — Google says to use noindex or a password, because a disallowed URL can still appear in results without a snippet (Introduction to robots.txt). The file lives at the host root. Google’s write-up shows a Sitemap: line with a fully qualified URL (How to write and submit a robots.txt file).
noindex is a meta tag or X-Robots-Tag header. Putting noindex in robots.txt is not supported. If robots.txt blocks the URL, Google may never see the tag (Block search indexing with noindex).
Canonicals are how you tell Google which hostname and path is the real one. Redirects and rel="canonical" are strong signals; sitemap inclusion is a weaker hint. Do not use noindex to settle www vs apex — that removes a page instead of consolidating it (Consolidate duplicate URLs).
Sitemaps have a hard cap: 50,000 URLs or 50 MB uncompressed per file. List absolute https:// URLs you actually want in results — the canonicals, not every alternate (Build and submit a sitemap).
| Surface | Production | Staging / preview |
|---|---|---|
robots.txt | Allow the public site; point at the sitemap | Disallow, or do not publish a public host |
| Meta robots | Index money pages | noindex |
| Password | Off | On, when the host allows |
| Sitemap | Canonical live URLs only | Absent, or not submitted |
Discoverability checklist:
- View source on a money page: no
noindex -
https://www.example.com/robots.txt(and the apex, if it is a separate host) allows production - Sitemap lists absolute canonical URLs
- Canonical tags match the hostname you chose
- Title and meta exist on key templates
- Structured data only where the claim is true
Confirm demo content, leftover theme copy, and “lorem ipsum” are gone. Builder exports and rushed custom launches both fail this one.
What is the order of operations on website cutover day?
Order I prefer. Deviating is fine if you write the new order down. Improvising in the registrar panel is not.
- Deploy the production build to the host while DNS still points at the old site, or attach the production domain on the host without announcing it.
- Verify on a hosts-file override or a platform preview that uses production config (production IDs, production form endpoints).
- Flip DNS / assign the domain.
- Watch certificate provisioning on apex and www.
- Hit both hostnames. Confirm a single canonical home.
- Submit a test form with a unique string.
- Confirm a realtime analytics hit or a debug event.
- Request a nonsense path. Confirm status
404and a path home. - Paste the home URL into an OG debugger.
- Spot-check the redirect map.
- Tell the client the URL is live — and what not to cache-panic about.
Communicate TTL reality. Some networks will show the old site until caches expire. Have one sentence ready so the client does not “fix” DNS every ten minutes.
Cutover-day “do not”:
- Do not launch Friday at 6pm with no on-call
- Do not leave basic auth on production
- Do not test forms only on staging
- Do not let the client announce a URL you have not QA’d on the production domain
- Do not cancel the old host the same hour you cut DNS
Content QA the same window: walk primary nav, click footer links, open a private window for first-visit and consent states. Have a non-project human attempt the primary conversion path. If they cannot find how to contact you, fix that before ads.
Should you soft-launch or hard-launch a brand site?
Soft launch: domain live, limited announcement, watch errors for 24–48 hours, then campaign. Hard launch: domain flip aligned with the email and social blast.
| Signal | Soft launch | Hard launch |
|---|---|---|
| Campaign attached | Prefer soft | Only if the checklist is fully green |
| Migration with a long URL list | Soft — you will find missed 404s | Amplifies every miss |
| New domain, no legacy traffic | Either | Fine if OG, forms, and analytics are proven |
| Client insists on a date | Soft the domain early; blast on the date | Treat the date as a marketing event, not a DNS experiment |
Brand sites with heavy campaigns should soft-launch when possible. Hard launches amplify every missed redirect and every blank share card.
QA matrix before anyone hits send:
- iPhone Safari, Android Chrome, desktop Chrome and Safari
- Newsletter HTML links, if the campaign goes the same day
- Password gates off if the site should be public
- Favicon and app icons present
- Privacy and terms links work; copyright year current
- Placeholder copy gone on primary paths
How should staging differ from production at launch?
Staging and production are different sites that happen to share a repo. Treat them that way.
| Item | Staging | Production |
|---|---|---|
| Indexing | noindex and/or password | Indexable money pages |
| Analytics | Staging property or none | Live G- ID |
| Forms | Dummy inbox or off | Live endpoint + live notify |
| CMS dataset | Preview branch | Published production |
| Env vars | Test keys | Live keys |
| robots | Block or private host | Allow + sitemap |
Hygiene checklist:
- Preview hostnames cannot be confused with production in the client Slack
- Production does not read staging CMS data
- Production does not ship
noindexbecause someone copied the staging layout - Password gates removed from production
- Search Console and analytics properties created for the live host, not only the preview
I paste a shortened go-live list into the project Notion or Linear and tick it in public with the client. Shared visibility reduces “I thought you did DNS” arguments. Cinema-grade craft includes the boring reel.
What should you check in the first week after launch?
Ownership in Search Console is not optional if you care about coverage. A verified owner has the highest permission set; methods include an HTML file, a meta tag, or a DNS record. Domain properties require DNS (Verify your site ownership).
| Window | What you look at | What you do |
|---|---|---|
| T+1 hour | Certs, forms, analytics realtime, OG debugger | Fix anything still red |
| T+24 hours | 404s in logs or host analytics | Add redirects for real misses |
| T+48 hours | Consent + events after tags settle | Confirm convertible events exist |
| T+7 days | Search Console coverage, sitemap, crawl errors | Batch-fix; do not celebrate the chart yet |
Post-launch checklist:
- Search Console (and Bing, if you use it) ownership verified
- Sitemap submitted or at least discoverable
- Crawl / 404 report reviewed
- Convertible events visible in analytics
- Client trained on the CMS if they will edit
- Redirect map updated for missed paths
- Performance re-check after marketing tags settle
- Retro: one lesson added to the template checklist
Migrations multiply this week. Inventory old URLs with a crawl before you redesign. Preserve slugs when you can — changing every slug for aesthetics is an expensive vanity move. Keep the old host available briefly for emergency rollback when the contract allows.
Migrations still answer to the same craft standard in Websites That Feel Like Films. They just add a redirect subplot.
What failure modes blow a website launch?
These are the ones I have actually cleaned up. Not theoretical.
| Failure | What it costs | What you do instead |
|---|---|---|
| Deleted MX while editing A records | Inbound mail dies during the announcement | Change only website records; treat MX as sacred |
Staging G- ID on production | A week of “the campaign did nothing” | View-source the live domain before you toast |
| Form tested only on preview | Zero leads; client blames the design | Unique-string submit on the custom domain |
| Soft 404 (pretty page, status 200) | Crawlers think junk URLs are real pages | Confirm status 404 in headers |
| No OG image on the blast URL | Every share looks unfinished | Debugger on production, then send |
noindex left on money pages | The new site is invisible | View-source before DNS praise |
| Friday 6pm cutover, no on-call | Weekend DNS panic, unpaid | Tuesday–Thursday, named human |
| Old host cancelled at the flip | No rollback when certs or records fail | Keep the old host until T+7 |
| Client announces a URL you have not opened | Public 404 or password wall | QA the production hostname first |
Anti-pattern, short form: launching on hope. The checklist is the deliverable. Save it in the repo or Notion. After each launch, add one lesson at the bottom so the next cutover is calmer than the last.
If you want a brand site launched with ops discipline — not hope — the websites lane is built for that sprint. Explore /websites.
FAQ
What belongs on a website launch checklist?
DNS and SSL, a redirect map, robots and sitemap hygiene, production analytics, a live form test, a branded 404 that returns status 404, Open Graph on the URLs you will share, and a named rollback. Customize by stack. Do not skip owners. If a box has no name next to it, it will be the box that fails.
What is a go-live checklist for a marketing site specifically?
Domain canonicalization (apex vs www, HTTP vs HTTPS), campaign-ready Open Graph, a published tag-manager container with the production GA4 ID, a CRM or inbox test lead you then delete, and a clock that matches the announcement. Add the core technical list above. Marketing sites fail in public — the blast is part of QA.
When should we lower DNS TTL?
Before a planned cutover, when you may need to correct records quickly. Lower it at least one full old-TTL window ahead of the flip. Raise it again after the site is stable so you are not paying extra lookups. Proxied Cloudflare records already sit on a 300-second Auto TTL you cannot edit; DNS-only records are the ones you actually shorten.
Should we launch on a Friday?
Only if a named person is accountable over the weekend and the change is low risk — a copy tweak, not a DNS cutover. Most brand cutovers are happier Tuesday through Thursday. Friday at 6pm with no on-call is how a missing MX record becomes a Monday crisis.
How do we handle the old site?
Archive or keep a backup, map top URLs from analytics and a crawl, and redirect the ones that deserve a new home. Do not leave the old host serving competing content on an alternate domain without a plan. Do not cancel the old host the hour you flip DNS unless you enjoy gambling.
What if analytics can wait?
It can wait only if you accept blind weeks. Put the production measurement ID on the live domain and fire one test event before anyone announces. Retroactive guessing is a poor substitute for instrumentation. Staging hits in a sandbox property will not reconstruct a campaign.
CTA
Ship the call sheet, then flip DNS. If the boring reel is still a pile of Slack guesses, we should run the sprint with owners named.
Explore custom brand sites or book a website sprint.
What questions does this article answer?
- What belongs on a website launch checklist?
- DNS and SSL, a redirect map, robots and sitemap hygiene, production analytics, a live form test, a branded 404 that returns status 404, Open Graph on the URLs you will share, and a named rollback. Customize by stack. Do not skip owners. If a box has no name next to it, it will be the box that fails.
- What is a go-live checklist for a marketing site specifically?
- Domain canonicalization (apex vs www, HTTP vs HTTPS), campaign-ready Open Graph, a published tag-manager container with the production GA4 ID, a CRM or inbox test lead you then delete, and a clock that matches the announcement. Add the core technical list above. Marketing sites fail in public — the blast is part of QA.
- When should we lower DNS TTL?
- Before a planned cutover, when you may need to correct records quickly. Lower it at least one full old-TTL window ahead of the flip. Raise it again after the site is stable so you are not paying extra lookups. Proxied Cloudflare records already sit on a 300-second Auto TTL you cannot edit; DNS-only records are the ones you actually shorten.
- Should we launch on a Friday?
- Only if a named person is accountable over the weekend and the change is low risk — a copy tweak, not a DNS cutover. Most brand cutovers are happier Tuesday through Thursday. Friday at 6pm with no on-call is how a missing MX record becomes a Monday crisis.
- How do we handle the old site?
- Archive or keep a backup, map top URLs from analytics and a crawl, and redirect the ones that deserve a new home. Do not leave the old host serving competing content on an alternate domain without a plan. Do not cancel the old host the hour you flip DNS unless you enjoy gambling.
- What if analytics can wait?
- It can wait only if you accept blind weeks. Put the production measurement ID on the live domain and fire one test event before anyone announces. Retroactive guessing is a poor substitute for instrumentation. Staging hits in a sandbox property will not reconstruct a campaign.
- support.google.com
- support.google.com
- developers.cloudflare.com
- developers.cloudflare.com
- developer.mozilla.org
- support.google.com
- support.google.com
- docs.netlify.com
- developer.mozilla.org
- developers.google.com
- ogp.me
- developers.facebook.com
- developers.google.com
- developers.google.com
- developers.google.com
- developers.google.com
- developers.google.com
- support.google.com
- example.com`
- example.com`
- `
- `
- example.com
Last reviewed
Websites
Websites Creator Site or Business Site for the house?
Creator Site ($3,500) is tour, listen, join, buy. Business Site ($8,000) is the register. Pick after the $1,500 sprint — not before you have seen the house.
Websites Discord is unpaid labor — put a register on the house
Keep Discord if the room lives there. The house is the owned URL, checkout, and join path so the community collects money instead of leaking attention.
Websites Spec buyers will not order what they cannot see
A forge or architectural-metal site is a spec packet: commissions, process, materials. It is not a tap-to-call HVAC homepage. AllCity is the phone. Matt Coffey is the work.
Websites A cultivation site is not a wellness brand
Cultivation sites sell lots, COAs you actually have, and wholesale inquiry — not a leaf on black with invented medical copy.
Will's Journal in your inbox.
What I learned this week building for shops, floors, and houses.
You're on the list.
Sign-up failed — try again.
By subscribing, you agree to the Privacy Policy.