I run a small web agency in Greece, and on the side I build niche tool sites. My latest one is Fortnite Account Value: free calculators that show what a Fortnite locker would cost in the Item Shop, how rare each skin is, and what's in the shop today.
It started as four calculators. This week it grew into a daily Item Shop tracker with full history for thousands of items, share images, three currencies and a Chrome extension. Here's how it's built and what I learned.
The stack: boring on purpose
- PHP 8.1+, MySQL 8, vanilla JavaScript
- No framework, no build step, no npm on the server
- One front controller (
index.php), one folder per tool (tools/<slug>/), a small admin panel and a web installer
Why no framework? These sites run on cheap shared hosting, I build several of them on the same skeleton, and I want to upload a folder over FTP and be done. A 60-line router and a few static classes (Database, Settings, Page) cover everything I need.
Data: one sync, every day
Cosmetics come from Fortnite-API.com, an unofficial community API. A cron job hits a secret URL just after the shop resets at 00:00 UTC:
curl -s "https://fortniteaccountvalue.com/cron/sync/?key=SECRET" The sync imports every cosmetic type (outfits, pickaxes, emotes, gliders…), then reads today's shop. Originally I only used the shop to update a "last seen" date and threw the line-up away. That turned out to be the most valuable data I had.
Now every run stores the whole day: each offer, its section, its price, whether it's a bundle, and the items inside it. Each item also keeps its full list of shop dates. With that I can show things people actually search for:
- Today's Item Shop, with a "Back after 2.4 years" or "New" label on every item
- A page for every past day (
/item-shop/2026-11-03/) and a calendar of all of them - A year × month history grid on every item page, with its longest gap
- "Longest gone from the shop" lists per item type
Keeping the history as a comma-separated TEXT column instead of a separate table sounds lazy, but it means one row per item, and appending today's date is a single UPDATE:
UPDATE cosmetics SET shop_dates = CASE WHEN shop_dates IS NULL OR shop_dates = '' THEN ? WHEN LOCATE(?, shop_dates) = 0 THEN CONCAT(shop_dates, ',', ?) ELSE shop_dates END WHERE id = ? 
