Handoff example. A website, handed to an agency.
When an agency hands me a bounded piece, this comes back with the code: what we agreed, how each point was checked, the results on the day, what the work does not do, how to change it and how to undo a release. Here it is filled in for the website demo, a four-page site for a bicycle repair workshop.
1. The scope as agreed
- Four pages: home, services and prices, about the workshop, and a booking request page; with a thanks page and a page for a missing address.
- A booking request form handled by Netlify Forms, with a hidden field that catches spam. Each request is kept under Forms in Netlify and sent on by email notification.
- Every sentence written from the shop's facts sheet, so nothing on the site is invented by the developer.
- Plain HTML and CSS, with one eight-line script that preselects the service a booking button names. The site works with scripts off.
- Delivered as source in your repository, with the build and the checks. The built folder deploys to the host the shop chose, here Netlify.
Not included: an editing screen, online payment, a booking calendar, the domain and hosting costs.
2. The acceptance checklist
Each line comes from the scope. The checks are scripts in the repository, so you can run them again.
| # | What must be true | How it was checked | Result |
|---|---|---|---|
| 1 | Every page reads well at desktop width and on a phone, with no sideways scrolling. | The probe loads each page at 1440 and 390 pixels wide. | Pass |
| 2 | Each price card's booking button opens the form with that service chosen, and the choice can be changed. | The probe presses the four buttons on the home and services pages. | Pass |
| 3 | The form sends a request and lands on the thanks page, with scripts on and off. | The probe fills and sends the form to a local stand-in for Netlify's handler. | Pass |
| 4 | The thanks page says plainly that nothing is booked until the shop confirms. | The probe reads the thanks page. | Pass |
| 5 | No accessibility violations at WCAG 2.1 levels A and AA. | axe 4.13.0 on every page at both widths. | Pass |
| 6 | Nothing loads from another host, and only the site's own style and script run. | The probe reads each page's security policy and every request it makes. | Pass |
| 7 | Every sentence matches the facts sheet. | A script traces each sentence to the sheet. | Pass, 391 of 391 |
| 8 | Pages load fast on a phone. | Lighthouse 13.5.0, mobile preset. | Pass, performance 100 |
3. The check results on the day
The probe's run of 1 October 2026 on source revision 9237d92: 378 checks passed, 0 failed. What it recorded for each page:
| Page | Width | Links checked | Sideways scroll | axe rules passed | Violations |
|---|---|---|---|---|---|
| Home | 1440 and 390 | 22 | 0 px | 24 | 0 |
| Services | 1440 and 390 | 18 | 0 px | 22 | 0 |
| About | 1440 and 390 | 14 | 0 px | 22 | 0 |
| Booking request | 1440 and 390 | 14 | 0 px | 31 | 0 |
The test request it sent carried the form name, the spam field and the six fields the shop reads: name, phone, email, service, day and message. Lighthouse, 25 September 2026, five pages on the mobile and desktop presets: performance, accessibility and best practices 100 on all ten runs; largest content painted in 0.7 to 0.9 seconds on the phone preset.
4. Known limits
- The form sends a request; it books nothing. The shop confirms each one by text or email.
- Netlify's spam filter can flag a request with a made-up address. A flagged request goes to Spam submissions under Forms, not to the inbox, so that list needs a look now and then.
- The checks run in Chromium. Safari and Firefox were not tested by script.
- Search scores are 58 and 54 because every page asks not to be listed, as a demo should. A live site drops that one line and is listed.
- There is no editing screen: a change is made in the source and published again, as below.
5. Changing the site
A price, the opening hours or a page's words, in about ten minutes:
- Edit the source in
src/. A price shows on the services page and on the home page's price cards; the hours show in the footer every page shares (src/layout.html) and on the home and booking pages. Searchsrc/for the old value and change each place it appears. - Run
npm run build, thennpm run probe. Publish only when it reports 0 failed. - In Netlify, drag the
distfolder onto the project's Deploys page.
6. Rolling back a release
- In Netlify, open the project's Deploys page.
- Open the last deploy that worked.
- Select Publish deploy. The site switches back at once; nothing is rebuilt.
Netlify keeps earlier deploys for 30 days on the free plan and 90 on paid plans, and always keeps the live one and the most recent. Further back, build the earlier revision from the repository and drop it again. If the project publishes from Git automatically, the next push replaces the rolled-back version.
7. After handoff
For 30 days, anything that fails the checklist is fixed free. I reply within one working day, except during an absence announced a week ahead.
Have a bounded piece? Send the task, the stack and the deadline.
Tell me about the piece