Skip to content

feat(pricing): a dated Black Friday sale with its own page, banner, band and sale prices - #135

Merged
datlechin merged 1 commit into
mainfrom
feat/black-friday-2026
Nov 2, 2026
Merged

datlechin merged 1 commit into
mainfrom
feat/black-friday-2026

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

A dated Black Friday sale, defined once in pricing.json's new campaign: 40% off Pro one-time and Pro yearly with the Polar discount BLACKFRIDAY2026, live from 2026-11-24 00:00 UTC until 2026-12-01 08:00 UTC. The site switches on and off by itself at those instants, with no deploy.

  • /black-friday, in every language, on one URL kept from year to year. Before the sale it states the window and the prices. During it, both offers can be bought from the page with the code attached. After it, the title, heading and description say the sale has ended and nothing is offered.
  • While the sale is live:
    • A black banner with a per-second countdown takes the slot above the header on every page except the sale's own. It can be closed for the rest of that sale (WCAG 2.2.2), stored as tablepro:campaign-closed, which the privacy policy now lists in every language.
    • A black band sits above the homepage hero and Pricing's header.
    • The Pro card shows the struck list price, the sale price and a tag. The yearly card says the price covers the first year and what it renews at.
    • Checkout from the site sends the code. It does not when the reader's regional discount takes more off, because Polar takes one discount per order.
  • Honest reference prices: each struck price says since when it has been the regular price. The sale's page FAQ says prices changed on 2026-11-02 and links the post that explains why.
  • No page crosses a boundary:
    • In the 70 minutes before the start or the end, CacheHtmlAtEdge shortens s-maxage and stale-while-revalidate so every cached copy expires at that instant.
    • A head script drops the sale before first paint for a reader whose clock is past the end.
    • useCampaign ends it in a tab left open, and never starts it on the reader's clock.
  • Rules: positioning §9 gains "Dated sales", which records what a sale may say and where. It still never says "save N%" and still never names the regional discount outside the plan block.

Ships together with

  • The Polar discount BLACKFRIDAY2026, already created (40%, once, Pro Lifetime and Pro Yearly, same window).
  • No change to TableProApp/license: /checkout already accepts discount_code.

Tests changed on purpose

  • TopBannerTest, LanguageBarTest, PricingPageTest, RegionalPricingTest and EdgeCacheTest now run after the sale has ended. They describe the license banner, list prices and the usual cache lifetimes, and they would otherwise fail in CI during the sale week or the hour before it. CampaignTest and CampaignPageTest cover the sale.
  • TopBannerTest: the banner prop now carries its kind.
  • RegionalPricingTest: the sale's page also asks for the regional discount, only to leave the code off. It never names it.
  • PricingDataTest pins the campaign to the Polar discount. LandingTest, LocaleRoutingTest, LlmsTxtTest (the page is left out of llms.txt), SeoLengthsTest, ContentParityTest ("Black Friday" is a kept name) and PublicContractsTest (four banner and band events) know the new page.

Checks run

  • The full Pest suite with the SSR service up: 2290 passed, 1 skipped. Run again with the sale forced live: all passed except the two tests that pin its real dates.
  • In a real browser, an open /black-friday tab turned live at the start instant and an open Pricing tab dropped the band, the banner and the sale prices at the end instant.
  • npm run typecheck, npm run test:js and pint --test pass.
  • Screenshots of the home page, Pricing and /black-friday checked at 1440px and 390px, light and dark, with the sale forced live locally.
  • An independent review's findings are fixed: a typed code no longer shows the sale price, the end check re-arms and re-checks when a tab becomes visible, closing the banner moves focus to the header, the band no longer opens the outline before the page's h1, and the page answers 404 if pricing.json names no sale.

@datlechin
datlechin merged commit 08b3e50 into main Nov 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant