Skip to main content
← Case studies

Case study

Thunder Road Bar & Grill

Burgers, wings and a bar in Midway, with the menu, reservations and hiring online.

Thunder Road had a vendor site that cost a lot, was hard to get changed, and looked flashier than the restaurant it was selling. The owners wanted something that fit the place, cost less to keep, and put the menu, hours, reservations and hiring in front of customers without a phone call.

I rebuilt it from scratch as React apps over a PHP and MySQL API on GoDaddy cPanel, live in November 2025. Over the next ten months it grew an admin where managers run the menu, reservations, job applications, messages, photos, staff accounts and a weekly schedule. Online ordering goes to ChowNow; the site itself takes no payments.

In September 2026 I moved it to Next.js on Vercel, with Turso for data, Cloudflare R2 for photos and SendGrid for mail. The new server was held to 287 requests recorded from the PHP build, the recording turned up 19 production bugs that the owner settled with 20 decisions, and the cutover took 26 minutes after closing with no form lost.

What they wanted

An affordable upgrade over an expensive vendor site they could not see into, which was slow to change and too slick for a local bar and grill. They wanted a site that looked like the place and that they could keep current themselves.

The same ownership group runs several of the businesses I build for. Thunder Road was my first client site, and I still run it.

At a glance

Client
A bar and restaurant in Midway, North Carolina.
Launched
November 2025
Moved to the current platform
September 2026
Runs on
Next.js 16 route handlers on Vercel, The same React and Vite apps, served from the same origin, TypeScript, Turso (libSQL), Cloudflare R2 for photos, with sharp for resized copies, SendGrid for outbound mail, Cloudflare DNS, Vercel Web Analytics

What was built

The public site

One page that scrolls through the menu, reservations, about and careers, with its own address for each section. It is dark, plain and quick to read on a phone, and every word and photo on it comes from the admin.

Order Online

A button in the header and footer that opens the restaurant's ChowNow ordering page. Orders and payments happen there; the site takes no payments.

Hero slideshow

Photos the managers choose in Settings rotate at the top of the page under an editable title, subtitle and two buttons. With nothing chosen, six photos of the restaurant show instead.

Menu

Category cards with photos open like an accordion. Items can show two sizes and two prices, categories can run in one to three columns, and an item with no price shows without one, for things listed so customers know they exist.

Reservation requests

Name, phone, date, party size and notes. Time slots come every 30 minutes from the kitchen hours, and a guest who needs another time can send a special timing request in words. Staff confirm each one by hand.

Careers

Open positions from the admin and an application form with availability, experience, a cover letter and a resume link. Extra questions can be added to the form, and their answers are kept with the wording that was asked.

Hours and contact

Kitchen and bar hours in a footer dialog, a contact form in another, and an About section with a map that loads when someone taps it.

Spam traps without a puzzle

A hidden field on every public form and per-visitor rate limits. Customers never see a CAPTCHA.

Screenshots show demonstration data on a local copy of the site, set up to show everything the design can do. No customer records appear anywhere in these pages.

Thunder Road Bar & Grill homepage hero on a desktop screen
The top of the homepage: the hero slideshow with its title and two buttons, and the header with Order Online.
Menu section with the first category card expanded to show its items
The menu with one category open: items in columns, two sizes and prices where an item has them, and an item listed with no price.
Reservation form filled in with sample details
A reservation request filled in with sample details before it is sent. Picking a date fills the time list from that day's kitchen hours.
Careers section with the job application form filled in with sample details
The careers section: open positions beside an application with sample answers, a resume link and the extra questions.
Hours dialog listing kitchen and bar hours
The Hours dialog from the footer, with kitchen and bar hours for each day.
Thunder Road Bar & Grill homepage on a phone
The homepage on a phone, with the header folded into a menu button.
Menu category cards with photos on a phone
The menu on a phone: category cards with photos that open one at a time.
Reservation form on a phone showing a special timing request
On a phone, a guest who needs a time outside the listed slots sends a special timing request in their own words.

PageSpeed Insights

Median of at least 3 runs per device, 2026-10-06. Run it live ↗

Desktop

Performance
100 out of 100, Good
Accessibility
100 out of 100, Good
Best practices
100 out of 100, Good
SEO
100 out of 100, Good

LCP 676 ms · CLS 0.005 · TBT 8 ms

Phone

Performance
88 out of 100, Needs work
Accessibility
100 out of 100, Good
Best practices
100 out of 100, Good
SEO
100 out of 100, Good

LCP 3.4 s · CLS 0.001 · TBT 23 ms

What the owner runs

Behind the login

The admin lives at /admin on the same site. Three roles decide what each person sees: owners see everything, managers run the restaurant's content and requests, and staff see their own shifts and password. Every action checks the role again on the server.

Menu

Categories with drag-to-reorder, column count, a photo and a switch to hide descriptions. Items with two size and price pairs, availability, and a check before saving an item with no price.

Reservations

A list and a detail view with pending, confirmed, cancelled, completed and archived. Confirming or cancelling emails the guest once, only when the status actually changes. At phone width the list becomes cards.

Jobs

Applications move from new through reviewing, interviewed, hired or rejected, and show the answers to any extra questions and a safe resume link. Positions are added, edited and switched on or off here.

Messages

Contact form messages with a read flag and a status: new, in progress, responded or archived.

Media and photo framing

A photo library with uploads of any size. For each place a photo is used, such as a menu card or the hero, a manager picks which part of the original shows.

Staff accounts

Create accounts, set roles, switch access off and set passwords. The last owner cannot remove their own access.

Weekly schedule

Managers draft shifts by person and day, including bar shifts that end after midnight, then publish each day. Staff see only published shifts.

Audit log

Who changed what and when, filtered and paged, with an export. Entries are kept for 90 days.

Settings and hours

Business details, hero copy and photos, the wording of each section, the About text, footer contact and social links, and kitchen and bar hours for each day.

Three roles

Owner, manager and staff. The sidebar hides what a role cannot use, and the server refuses it anyway.

Admin menu module listing categories and items
The menu editor: categories in display order with their photo and columns, and the items in each.
Admin reservations list with sample requests in several statuses
Reservation requests by status, with a badge on special timing requests. Confirming or cancelling emails the guest once.
Admin jobs module listing sample applications
Job applications with their status, ready to open for the answers and the resume link.
Admin messages inbox with sample contact messages
Messages from the contact form, each with a read flag and a status.
Edit Media dialog with a photo and its framing controls
Editing a photo in the media library, where a manager chooses the framing for each place the photo is used.
Admin weekly schedule with sample shifts
The weekly schedule with published and draft shifts, including a bar shift that ends after midnight.
Admin audit log with filters and sample entries
The audit log: who changed what and when, with filters and an export.
Admin reservations shown as cards on a phone
Reservations at phone width, where the list becomes cards.

What it runs on

Two platforms, one site

The first version ran on shared cPanel hosting. The site now runs on the current platform, with the move recorded in the write-up.

Version 1, November 2025

Hosting
GoDaddy cPanel shared hosting, Apache with PHP 8.3
Database
MySQL (MariaDB 10.11) on the same host
Deploys
Built locally and uploaded as zip archives
Media
On the host, then Cloudflare R2 from May 2026
Email
SendGrid from December 2025

Today, since September 2026

Domain
trbgmidway.com; www redirects to the bare domain
DNS
Cloudflare, with the photo CDN on its own subdomain
Hosting
Vercel; a merge to main deploys, and previews are private
Database
Turso (libSQL), with a separate database for previews
Storage
Cloudflare R2: a public bucket for photos and a private one for originals and large uploads
Email
SendGrid only; the domain has no mailboxes, and site mail lands in the restaurant's existing inbox
Analytics
Vercel Web Analytics, no cookies
Rollback
The PHP build and its database stay on the cPanel host
Checks
Lint, types, build, the 287 recorded requests and an integration suite on every change, run on self-hosted runners

What it does now

Online ordering works, and reservation requests, job applications and messages arrive steadily.

  • •Owners and managers rarely edit the site. They sign in to check job applications and messages.
  • •Reservation requests come in through the site and staff confirm them by hand. The guest hears back when the status changes.
  • •Orders and payments go through ChowNow from the Order Online button.
  • •Day to day it runs on its own: updates merge after the checks pass, and I step in when something breaks.

“The old site cost a lot and looked like somebody else's restaurant. This one brings in reservations, job applications and messages every week, and we almost never have to touch it.”

Owner, Thunder Road Bar & Grill

The business and what it needed

Thunder Road Bar & Grill is a bar and restaurant in Midway, North Carolina. It serves burgers, sandwiches, wings, flatbreads and salads from the kitchen, runs a bar with its own hours, takes reservations for tables, and hires staff. Takeout orders go through ChowNow.

The restaurant belongs to the same ownership group as several of the other businesses I build for. It was my first client site, and I still run it.

Someone on a phone wants to see the menu, find out whether the kitchen is open, book a table, order food, or apply for a job. The staff want to hear about each of those without having to watch another system. The owners want the menu and hours to be right without paying someone every time a price changes.

In the owners' terms, they wanted an affordable upgrade. Their old site cost too much, they could not see what they were paying for, and changes were slow. It also looked flashier than the restaurant. Thunder Road is a local bar and grill, and the site was too slick for it. They wanted a site that looked like the place and that they could keep current themselves.

What was there before

Before the rebuild the restaurant had a site run by an outside vendor. The owners describe it as expensive and opaque: they paid for it, but they could not see how it worked or change it themselves, and getting an update made took time. It was polished in a way that did not match the room.

There was no admin the managers could use for the things the restaurant actually handles every week. Menu changes, hours, job openings and photos all went through the vendor.

Version 1: the cPanel build

Starting over

I started the rebuild on October 4, 2025, as a React app built with Vite and styled with Tailwind. The first backend was a small Node server.

The hosting decided the next step. The restaurant's account was GoDaddy cPanel shared hosting, and that host does not allow a long-running process, which a Node server needs. On November 14, 2025 I converted the backend to PHP so it could run under Apache like any other cPanel site. Support for a separately hosted Node and PostgreSQL setup went in the same day and came back out.

The site was live on cPanel by November 20, 2025. The public side was one page with the menu, reservations, an About section with a map, a careers form, and hours and contact dialogs in the footer. The admin covered the menu, media, and job positions and applications.

The first months

In December 2025 I removed the last of the Node backend and finished the PHP API. The same month brought SendGrid for mail, a rich text editor for the About section, branded error pages, and an audit log. Between December 25 and 28 I did a performance pass: fonts hosted on the site, images in several sizes so a phone downloads a phone-sized photo, a hero image that paints without waiting for the app, sizes fixed up front so the page does not jump while it loads, and longer cache lifetimes for files that never change.

In January 2026 the site moved to a permanent dark theme, with DM Sans hosted on the site for the hero and menu. On March 2 the Order Online buttons were wired to the restaurant's ChowNow page.

Tightening it up

From May 2026 I went back through the site with the standards I was settling on across all the client sites. On May 11 the public forms got spam traps. On May 14 secret scanning went into the repository. On May 25 the owner got a System Checks page in the admin. On May 27 photos moved to Cloudflare R2, through a bridge in the PHP code. The same month added the special timing request on reservations, split the public and admin apps, and adopted the shared backend and admin kits the other sites use.

From late May, changes went through pull requests. The August and September work:

  • •PR #16 (August 5) added an integration suite that runs the PHP API against a real database on every change.
  • •PRs #21, #23 and #25 (August 7) added staff roles, a weekly work schedule and staff account management.
  • •PRs #30 to #34 named mail settings by what they do and removed an SMTP block that had never been used.
  • •PRs #45 to #53 (August 22) were another performance pass: one font download where there had been two, a hero that rotates and loads one slide ahead, and the first menu card loading first.
  • •PRs #54 and #55 (August 22) let managers choose which part of a photo becomes a menu card.
  • •PR #57 (August 30) stopped the last owner from switching off their own access.
  • •PR #76 (September 11) made a framing belong to the place a photo is used, so the same photo can be framed one way for the hero and another for a menu card.
  • •PR #92 (September 15) fixed two bugs on the live cPanel site: the reservations list crashed when it opened, and every reservation showed a day early.

What it taught me

Thunder Road was the first site I built for a client, and it shows in the history. For its first seven months every change went straight to the main branch, and the first merged pull request is #4, on May 23, 2026. I picked a backend before I knew what the host allowed. The real-database test suite came in August 2026, ten months after the first commit.

Every site since has started where this one ended up: pull requests and required checks from the first day, the shared kits, a decision log, and hosting chosen before the first line of backend code. I brought those habits back here too, which is most of what the 2026 work above is.

Why the site moved, and what changed

Why move

By September 2026 the cPanel build worked, but the hosting set its limits. Deploys meant building locally and uploading zip archives. The PHP, the database and the uploads all lived on one shared account. The host's clocks did not agree with each other or with the restaurant. And the other sites in the same family were moving to Vercel and Turso, where a merge deploys, previews are automatic, and one way of working covers every site.

The move kept the React apps the customers and managers already used. What changed was everything under them: Next.js route handlers on Vercel in place of the PHP API, Turso in place of MySQL, and Cloudflare R2 as the only home for photos.

Holding the new server to the old one

A rewrite of an API that works is a good way to break things nobody notices for a month. So before writing the new server, I recorded the old one.

I scripted 287 requests against the real PHP API and saved every answer: what a visitor sees, what each role can and cannot do, sign-ins, lockouts, refusals, uploads and every form. The accounts covered a visitor, staff, a manager, two owners and a brand new staff member. A further 294 cases recorded the PHP helpers on their own: the HTML sanitizer, the validators, the sign-in tokens, the email bodies, the photo crop math and the price encoding.

The Next.js server was built in PR #93 on September 15, 2026 and replays all of it on every change. Where it deliberately answers differently, the difference is a file in the repository with the request it applies to and the reason.

The 19 bugs

Recording a working system carefully turns up what was never working. The recording found 19 bugs in production. Two were serious. A sign-in token kept working for up to 24 hours after its account was deleted or switched off. And any signed-in staff member could read, change and delete job applications, because those routes checked that someone was signed in without checking their role.

The rest were smaller, and each one was real:

  • •Archiving a job application blanked its status, because the database quietly stored an empty value for a status it did not list.
  • •A reservation date that was not a date was saved as zeros, and a party of zero was accepted.
  • •A menu item saved without a price failed and sent me an alert.
  • •Staff could not change their own password, and typing the wrong current password signed people out.
  • •Confirming a reservation twice emailed the guest twice.
  • •A bar shift that ended after midnight could not be entered.
  • •Admin times showed an hour or two early.

I wrote each one up as a question with a recommended answer, which came to 20 decisions, and all 20 were settled on September 15. One answer differed from my recommendation: a menu item with no price saves as free, because some items are on the menu only so customers know they exist. The port settled every bug as decided, and the tests hold each answer in place.

Three clocks into one

The worst of the time bugs came from the host. MySQL ran on Mountain time, the web PHP on Central, the command line on UTC, and the restaurant is on Eastern. Every column was converted using the clock that had written it. Turso now stores instants in UTC, with a database rule that refuses anything else, and the site shows and decides everything on Eastern time. The tests run in three different time zones so a mistake cannot hide behind the test machine's own clock.

The cutover

The move ran after closing, in a 26-minute window from 11:14 to 11:40 p.m. Eastern on September 15 (03:14 to 03:40 UTC on September 16).

  • •The maintenance page went up, so no visitor could submit a form during the move.
  • •I backed up and exported the MySQL database, loaded every row into Turso and checked it against the export.
  • •DNS moved to Vercel.
  • •A delta import read anything written above the export's highest ids, before and after the DNS change. All three runs found nothing, so no reservation, application or message was lost.
  • •The maintenance page came down.

The cutover turned up three traps, all fixed that night or the next day:

  • •The cPanel maintenance switch had never worked, because its rule ran after the rule that serves files. PR #94 fixed the order, so the rollback has a working switch.
  • •The Vercel command line stored an empty value when an environment variable was piped in. Environment variables are now set through Vercel's API.
  • •A production deploy from a local checkout skipped ignored files and shipped a build with no page shells, so unknown addresses answered with errors. Production is built only by the git integration now.

The same day, PR #95 recorded the deletion of three leftover DNS records for an old admin subdomain that pointed at an unrelated site. The next day PR #99 made the home page and the admin go through the app's own route, so the maintenance switch covers them too.

Mail

Mail goes through SendGrid only, as it had since December 2025. The domain has no mailboxes. Reservations, applications and messages are sent from a no-reply address on the domain to the restaurant's existing inbox. A guest gets an email only when their reservation's status actually changes. Server errors email me, throttled so one fault sends one alert. Since PR #112 every send is tagged with the site's name in the shared SendGrid account, and since PR #121 site mail carries no open-tracking pixel, because the pixel cost another family site points with spam filters.

After the move

  • •PR #97 (September 17) and later #115 made the database client reconnect after a failed transaction. The fix was carried to the other ported sites.
  • •PR #106 moved CI onto my own self-hosted runners.
  • •PRs #111, #113 and #114 tell someone whose tab is out of date to reload, in the admin and on the public site, before a stale page fails on its next click.
  • •PR #117 rewrote the documentation to describe the system that runs.
  • •PR #125 gave every page its own canonical address and made the status pages answer with their real status codes.
  • •PR #126 added Vercel Web Analytics and PR #127 rewrote the privacy page to match what the site collects.
  • •PRs #128 and #129 store the careers form's extra answers with the application and show them in the admin.
  • •PR #130 accepts only web links for resumes and never links one that is unsafe.

The public site, page by page

The public site is one page that scrolls through each section. Each section has its own address, so /menu, /reservations, /about, /careers and /contact open the page at that section. Privacy and terms have their own pages.

The header carries Menu, Reservations, About and Careers, the Order Online button, and a quiet staff sign-in link. On a phone it folds into a menu button that opens a drawer.

Hero

A slideshow of photos the managers choose in Settings. When none are chosen, the newest hero uploads stand in, and with no uploads at all six photos of the restaurant ship with the site. Over the photos sit a title, a subtitle and two buttons, all editable.

The menu is a set of category cards with photos. Tapping a card opens it to show its items, and opening another closes the first, so a phone never scrolls through the whole menu to reach the wings.

  • •An item can show two sizes with two prices, such as a small and a large.
  • •An item with no price shows with no price.
  • •A category can show its items in one, two or three columns, and can hide descriptions when the names say enough.
  • •A category without its own photo falls back to a bundled photo when its name matches one of the restaurant's standard categories.
  • •A notice above the menu covers anything that applies to all of it.

Reservations

The form asks for name, phone, email, date, party size and special requests. Once a date is picked, the time list fills with slots every 30 minutes across that day's kitchen hours. A guest who wants a time outside them can switch to a special timing request and write what they need. The server checks the date and the party size again before saving.

A reservation is a request. Staff confirm or cancel it in the admin, and a guest who left an email address hears back when they do.

About

The About text comes from the admin as rich text. Beside it is a map that loads only when someone taps it, with links for directions.

Careers

Open positions come from the admin, with a short note when nothing is open. The form asks for name, contact details, position, availability, experience, an optional cover letter and an optional link to a resume. The form takes a link in place of a file upload, so no documents are stored on the site. Extra questions can be added to the form, and the answers are kept with the exact wording asked. The admin has no screen for those questions yet, so they are added in the database.

The footer has the phone number, the address, social links, Order Online, and two dialogs: Hours, which shows kitchen and bar hours side by side, and Contact, a short message form. The footer's link columns are set in the database, with no admin screen.

Errors and stale tabs

Missing pages show a branded page with the right status code. A visitor whose tab has been open across a new release sees a notice to reload instead of a broken click.

What the owner runs

The admin is at /admin on the same site. There are three roles: owner, manager and staff. The sidebar shows each role only what it can use, and the server checks the role again on every request.

  • •Dashboard: counts of pending reservations, new applications and new messages.
  • •Menu: categories with drag-to-reorder, columns, a photo and a switch for descriptions, and items with two sizes and prices, availability and a check before saving with no price. The preview of the public menu folds away until someone wants it.
  • •Reservations: a list and a detail view, with pending, confirmed, cancelled, completed and archived. Special timing requests carry a badge. At phone width the list turns into cards.
  • •Jobs: applications with their status, the answers to any extra questions and the resume link, plus the positions shown on the careers form.
  • •Messages: contact form messages with a read flag and a status.
  • •Media: the photo library, uploads, and framing. For each place a photo is used, a manager chooses which part of the original shows, and the site cuts that version from the kept original.
  • •Staff: accounts, roles, access on or off, and passwords. The last owner cannot lock themselves out.
  • •Schedule: shifts by person and day, drafted by a manager and published a day at a time. Staff see only what is published.
  • •Audit log: what changed, who changed it and when, filtered, paged and exportable.
  • •Settings: business details, hero copy and photos, each section's wording, the About text, footer contact and social links, and kitchen and bar hours.
  • •System Checks, for owners: whether the database, photo storage and mail are working.

Infrastructure

  • •Domain: trbgmidway.com. The www address redirects to the bare domain.
  • •DNS: a Cloudflare zone. The site points at Vercel, and the photo CDN has its own subdomain in front of R2.
  • •Hosting: one Vercel project serves the public app, the admin and the API from the same origin. A merge to main deploys production. Previews sit behind Vercel sign-in.
  • •Database: Turso. Since September 30, 2026 previews have their own database, photo buckets and mail key.
  • •Photos: two R2 buckets. The public one serves every photo and its resized copies. The private one keeps originals for reframing and holds large uploads for a day.
  • •Email: SendGrid only, from a key that can send mail and nothing else. The domain has no mailboxes.
  • •Analytics: Vercel Web Analytics on the public site since September 30, 2026. No cookies.
  • •Security: strict transport security, a content security policy, framing and type-sniffing headers, and no indexing of the admin.
  • •Rollback: the PHP build and its database remain on the cPanel host with the cutover backup.
  • •CI: lint, types, build, the recorded-request replay and the PHP integration suite on every change, on self-hosted runners, with a weekly security sweep.

Decisions worth explaining

Keeping the React apps through the move

The customers and the managers already knew the site and the admin. Rewriting the screens would have added risk to the move and given the owners nothing they asked for. So the move replaced the server and left the screens alone, apart from admin fixes. That is also what made the recording possible: the same apps talk to either server, so both had to answer the same.

Recording the old system before replacing it

Reading PHP and guessing how it behaves misses what it does in practice. Recording 287 real requests catches every refusal, every odd status code and every field the apps rely on. It also produced the bug list. Most of those bugs had been there since launch, and no one would have found them by reading.

Deciding each bug on purpose

Fixing a bug changes what someone sees. Refusing an old token is plainly right, but whether a menu item can be free is a business decision. Each bug went in as a question with a recommendation, and the one answer that differed, free items, was a case I would have gotten wrong.

Reservations are requests

Reservations are built into the site, and a person confirms each one. There is no third-party booking service, so there is no extra account or monthly bill, and the restaurant decides each table itself.

Online ordering stays with ChowNow

The restaurant takes orders and payment through ChowNow. Rebuilding that on the site would mean taking card payments and everything that comes with them. The site links to ChowNow, and the privacy page says plainly that the site takes no payments.

Large photos on a host with a request limit

Vercel caps a request at 4.5 MB, and a phone photo is often bigger. The admin shrinks photos over 4 MB in the browser first, and anything still too large goes straight to the private R2 bucket by a signed link that expires after a day.

Sign-in without cookies

The admin signs in with a token kept in the browser and sent with each request. With no session cookie there is no cross-site request forgery to defend against. The account and its role are read from the database on every request, which is what fixed the deleted-account bug. Sign-in locks after five wrong passwords in 15 minutes, and rate limits are kept in the database, since Vercel has no shared disk.

Maintenance mode that covers everything

On Vercel a switch makes the public pages answer with a maintenance page and refuses the three public forms, while the admin stays reachable. PR #99 moved the page shells out of the CDN's reach so the switch covers the home page too.

Preview isolation came late

At cutover, preview deployments shared production's database and photo storage. On September 19 previews got their own sign-in secret, because a token signed on a preview would have been accepted by production. On September 30 they got their own database, buckets and mail key. Both belonged in place from the first day.

What it does now

The site is live at trbgmidway.com. Online ordering works, and reservation requests, job applications and messages arrive steadily.

Day to day:

  • •The owners and managers rarely edit the site. What they do check is job applications and messages.
  • •Reservation requests arrive by email and in the admin, and staff confirm them by hand.
  • •Orders and payments go through ChowNow.
  • •PageSpeed results for desktop and mobile are measured and published on this case study page, with a link to run the test live.

The repository has 644 commits and 126 merged pull requests, from October 2025 to early October 2026.

Ongoing support

Maintenance is mostly hands-off unless something breaks.

  • •Dependabot opens updates, and safe minor and patch updates merge on their own once every check passes. Larger ones wait for me.
  • •A weekly security sweep checks every dependency for new advisories. PR #135 on October 5, 2026 gave the scheduled sweep its own Node runtime.
  • •Server errors email me, and I fix forward.
  • •The PHP build stays on the cPanel host as the way back, and the recorded requests keep the two builds honest with each other.
  • •Content changes the owners would rather not make themselves come to me, along with anything that lives in the database without an admin screen, such as the footer links and the careers form's extra questions.

Services this shows

Want something like this for your business?

Send the current site, the problem, and what should become easier. You will hear back within one business day.