Building a Sports Alert Tool That Gets Used Every Game Day
A friend needed a faster way to post player status alerts on social media during live games. I built Sports Shortcuts in a weekend.
A friend of mine works at Underdog Fantasy. Part of his job is posting player injury and status updates to social during live NFL and NBA games. Player goes down, gets ruled out, heads to the locker room, he needs that information up fast. Followers are watching the game in real time, and they want to know what happened before the broadcast catches up.
The problem was the process. He was typing these updates out by hand every single time. Same format, same structure, just different names, injuries, and days. On a busy NFL Sunday with six or seven games going at once, he might need to post 20 or 30 of these in a couple of hours. Typing “Status alert: Patrick Mahomes (ankle) questionable to return Sunday” from scratch every time is slow, and you make typos when you’re juggling that many games.
So he asked if I could build something to speed it up.
What I Built
Sports Shortcuts generates formatted status alert messages. You type a player’s name, pick an injury, choose the day, and the app spits out every variation of the alert you might need. One click copies it to your clipboard. Paste it into the social tool you use and you’re done.
Whole thing takes about five seconds. Type a name, click a card, paste. During a live game, those saved seconds add up.
It covers NFL and NBA, with different templates for each. NFL has 10 variations. NBA has 21, because basketball has more weird scenarios (ejections, technical fouls, players walking back to the locker room mid-quarter). The app auto-detects the day of the week so that’s one less thing to think about.
How It Works
It’s a form with autocomplete. I loaded full NFL and NBA rosters, so when you start typing a name, fuzzy search suggests matches. Type “Mah” and Patrick Mahomes pops up. Pick the player and the app auto-fills their team info. For NBA, it also fills in the mascot, since some templates use it.
Once the player is set, the app renders every message variation at once as clickable cards. Tap one, and the text copies to your clipboard. The card flashes green with a checkmark so you know it actually worked (the worst thing during a live game would be tapping copy, pasting, and finding out nothing copied). Everything runs client-side, no server calls, so it’s instant.
I built it as a PWA too, so it installs on a phone’s home screen and launches like a native app. After the first load, it caches the roster data and templates locally and never has to fetch anything again. No loading spinners. You open it and it’s ready.
The roster data was the part that actually tripped me up. My first approach was the BallDontLie API, which has a free tier with player data. The problem? The free tier returns every player in history. Not just active rosters. Every player who has ever played in the NBA or NFL. That’s roughly 15,000 names. The autocomplete was unusable. You’d type “James” and get 200 results going back to the 1950s.
So I started building a filter. The plan was to pull the full list from BallDontLie, then scrape ESPN’s roster pages to figure out which players were currently active. I got the ESPN scraper working and was about to wire up the cross-referencing logic when I realized the scraper already had everything I needed. Active players, team names, positions, all of it. The API was just dead weight. So I ripped out BallDontLie and went with ESPN alone. Fewer dependencies, cleaner data, and the autocomplete went from 15,000 names to around 1,700. Fuse handles spelling variations, so it doesn’t matter if you type “Patrick Mahomes” or “Patrick Mahomes II” or even “mahomez”. It finds the match.
The Tech
Stack is intentionally boring. It needed to be quick to build and reliable enough that it never breaks during a Sunday afternoon.
- React with TypeScript for the UI
- Tailwind for styling, with sport-specific themes (NFL in blue and red, NBA in blue and orange)
- Fuse.js for fuzzy player name search
- Vite for builds
- Workbox for the service worker and offline caching
- Netlify for hosting, free tier
One Weekend
The whole thing took a weekend. Friday evening I set up the project and got the basic form working. Saturday I built out the message templates, loaded the roster data, wired up autocomplete and copy-to-clipboard. Sunday was PWA support, dark mode, and deploy.
That’s the upside of a tool that does one thing. The scope was narrow enough that I could actually finish it. No auth, no database, no admin panel, no settings screen. A form that generates text. That’s it.
The message templates are just string interpolation. Nothing clever. The tricky part was getting the exact wording right for each variation. My friend would send me the format they use at Underdog, I’d build the template, he’d test it during a game and tell me what needed tweaking. Most of them landed on the first try, since the format was already standardized in his head from posting hundreds of these. He just needed a tool to spit it out faster.
It Actually Gets Used
This is the part I care about. The tool isn’t rotting in a repo somewhere. It gets used during live games, every week of NFL season and all through NBA season. Since launch it’s generated hundreds of alerts across Underdog’s social accounts. A few recent ones:
- “Status alert: Kyren Williams (ankle) questionable to return Sunday.”
- “Status alert: Puka Nacua (ankle) headed to locker room Sunday.”
- “Status alert: Luka Doncic (eye) headed to locker room Tuesday.”
- “Status alert: Jalen Brunson (leg) headed to locker room Wednesday.”
If you’ve ever scrolled past one of these and wondered why they all sound the same, now you know. There’s a tool generating them.
The consistency is sort of the whole point. Every alert follows the same structure, so followers learn to recognize the format at a glance. They see “Status alert:” and they know what’s coming. That kind of consistency is hard to keep up by hand across a team of people typing in a rush during a game. The tool just does it for them.
What I’d Do Differently
If I were starting over, I’d probably reach for Astro instead of a pure React SPA. The app doesn’t really need client-side routing or a virtual DOM for what amounts to a form and a bunch of text cards. Astro with a React island for the form would shrink the JS bundle and load even faster. That said, it’s been running reliably for over a year and nobody’s complained, so I’m not going to rewrite it for marginal gains.
Adding more sports has crossed my mind. The template system is generic enough that NHL or MLB would just mean new roster data and new message templates. The architecture handles it fine, I just haven’t had the request. If anyone running an NHL or MLB account is reading this and wants the same tool, you know where to find me.
Why This Project Matters
Sports Shortcuts isn’t a flashy portfolio piece. There’s no marketing site behind it, no design system, no login, no account, no email required. It’s a form that makes text. But it solves a real problem for someone who uses it under time pressure during live games. That’s what good software is supposed to do.
It also costs almost nothing to run. Static files on Netlify’s free tier, no server, no database, no monthly fees. The only ongoing cost is about $15/year for the domain. Build it right, host it cheap, let it do its job.
When someone asks what kind of work I do, this is the project I bring up. Not because it’s technically impressive (it isn’t), but because it shows how I work. Someone had a problem, they explained it to me, I built a tool over a weekend, and they still use it every game day. That’s the whole job.
If you’ve got a workflow where you do the same thing over and over, it’s probably worth automating. Sometimes the most useful tool is the dumbest one. Get in touch if you’ve got something like that and want to talk about building it. You can also read about another project I built for a friend or check out what goes into the cost of a website.
I serve small businesses across the Denver Front Range: Denver, Lakewood, Golden, Littleton, Boulder, Arvada, Aurora, Westminster, and Highlands Ranch.
What now
Need a website for your business?
I build custom websites for small businesses across Denver and the Colorado Front Range. Free consultation, no obligation.