A web-based World of Warcraft Adventure Guide and Mythic+ companion. Browse dungeon and raid encounters across every expansion, study boss abilities and loot, reference trash spells, and plan Mythic+ pulls on interactive dungeon maps.
Built with React, TypeScript, and Vite. All WoW data is pre-fetched from the Blizzard API at build time and served as static JSON - the app makes zero runtime API calls.
- Browse dungeons and raids for every WoW expansion
- View boss abilities organized as a recursive section tree that mirrors the in-game journal
- Filter encounters by difficulty (Normal, Heroic, Mythic, LFR)
- Loot tables with item-quality coloring
- Zone spell / trash ability reference for dungeons, including interrupt tagging
- Inline
[bracketed]spell references rendered as Wowhead tooltip links
- Interactive dungeon map editor (Leaflet-based) for the current M+ season
- Select mob spawns to build pulls, with notes, prev/next pull navigation, and a dedicated abilities view per pull
- Import existing MDT route strings from the clipboard, or export your own
- NPC tier coloring in a Plater-style palette (caster / elite / boss tiers), with a nameplate colors settings panel
- Top-10 Raider.IO runs per dungeon, auto-refreshed daily via GitHub Actions and served as featured routes
- Top-10 Warcraft Logs runs per dungeon, surfaced as outbound report links with a "Learning" mode that opens companion WCL views (enemy auras, enemy casts, damage taken, player debuffs) for studying a pull
- Save routes to
localStoragewith editable names; landing page shows dungeon tiles, featured runs, Warcraft Logs runs, and saved routes
- Current Mythic+ season overview with quick access to seasonal dungeons and the seasonal raid
- Global search (Ctrl+K) across all instances and encounters
- Breadcrumb navigation and a collapsible sidebar that becomes a mobile drawer under 768px
- Dark and light themes (persisted to
localStorage) - Changelog page listing recent GitHub commits
- Curated list of community tools (Raider.IO, Wowhead, Warcraft Logs, Three Chest, etc.)
- Node.js 18+ (see
.nvmrc) - A Blizzard API application for data fetching (optional - the repo ships with pre-generated data)
npm installnpm run dev # Vite dev server on port 5173
npm run build # TypeScript check (tsc -b) + Vite production build
npm run lint # ESLint
npm run preview # Preview the production build locallyThere are no tests; tsc -b && vite build is the primary correctness check.
To refresh the bundled JSON from upstream sources:
- Copy the env template and add your credentials:
cp .env.example .env # BLIZZARD_CLIENT_ID=... # BLIZZARD_CLIENT_SECRET=... # WARCRAFTLOGS_CLIENT_ID=... # WARCRAFTLOGS_CLIENT_SECRET=...
- Run one of:
npm run fetch-data # Current expansion only npm run fetch-data:all # All expansions (slow, rate-limited) npm run fetch-data:zone-spells # Zone spells only npm run fetch-raiderio-routes # Top M+ routes per dungeon from raider.io npm run fetch-warcraftlogs-runs # Top M+ runs per dungeon from Warcraft Logs
Register a Blizzard API app at develop.battle.net and a Warcraft Logs v2 API client at warcraftlogs.com/api/clients. The raider.io scraper does not require credentials.
WarcraftJournal is a single-page application with no backend. The Blizzard API and raider.io are only consulted at build time (or by the scheduled GitHub Action). At runtime the app reads from static JSON bundled into the build.
scripts/fetch-data.ts handles the main pipeline:
- Authenticates with the Blizzard OAuth2 API
- Fetches expansion, instance, encounter, item, and zone-spell data
- Scrapes Wowhead for missing spell descriptions and NPC classification tiers
- Applies manual overrides (
ZONE_NPC_OVERRIDES,INSTANCE_IGNORED_NPC_NAMES) for accuracy - Writes JSON files to
src/data/generated/:expansions.json- expansion metadatainstances.json- dungeons and raidsencounters.json- boss encounters with ability treeszone-spells.json- dungeon trash abilities with interrupt flags and NPC tiers
scripts/fetch-raiderio-routes.ts pulls the top-ranked timed M+ runs for each current-season dungeon from raider.io, resolves the attached keystone.guru route, validates the MDT string with the app's own decoder, and writes raiderio-routes.json. A GitHub Action (.github/workflows/update-raiderio-routes.yml) runs this daily at 06:00 UTC and commits any diff.
scripts/fetch-warcraftlogs-runs.ts authenticates with the Warcraft Logs v2 API (OAuth2 client credentials), queries the current M+ zone for encounter ids, fetches the top fightRankings per encounter, and writes report-link metadata for the top runs per dungeon to warcraftlogs-runs.json. A second GitHub Action (.github/workflows/update-warcraftlogs-runs.yml) runs this daily at 06:15 UTC, staggered 15 minutes after the raider.io job so the two don't race on the same ref. The script also supports --list-zones for discovering the current M+ zone id when the season rotates.
The data layer (src/data/index.ts) imports these JSON files and builds Map<slug, T> and Map<id, T> lookups for O(1) access. Helper functions (getInstancesForExpansion, getEncountersForInstance, filterSectionsByDifficulty) are the query interface used by page components.
Current-season configuration lives in src/data/currentSeason.ts as dungeon and raid slug arrays.
React Router 7 with nested, slug-based routes:
| Route | Page |
|---|---|
/ |
Home (expansion list + current season) |
/season |
Current M+ season overview |
/season/:instanceSlug |
Instance within the current season |
/season/:instanceSlug/:bossSlug |
Encounter within the current season |
/tools |
Community tool links |
/tools/mdt-route |
Mythic+ route editor (map, pulls, MDT import/export) |
/changelog |
Recent GitHub commits |
/:expansionSlug |
Expansion page (instance grid) |
/:expansionSlug/:instanceSlug |
Instance page (encounter grid + zone spells) |
/:expansionSlug/:instanceSlug/:bossSlug |
Encounter page (abilities, loot, overview) |
Routes are defined in src/router.tsx; pages live in src/pages/.
URL-driven, minimal contexts - no Redux or external store:
JournalContext- difficulty and active tab viauseSearchParamsThemeContext- dark/light theme, persisted tolocalStorageLayoutContext- sidebar/drawer stateDevModeContext- dev info panel, persisted tolocalStorageNameplateColorsContext- user-customizable Plater-style NPC tier palette
src/components/
cards/ InstanceCard, EncounterCard (grid display)
encounter/ OverviewTab, AbilitiesTab, LootTab
sections/ SectionTree, SectionNode (recursive boss ability trees)
zone-spells/ ZoneSpellSection (dungeon trash abilities)
mdt/ DungeonMap, RouteBuilderControls, MobInfoPanel,
SpawnContextMenu, RouteLandingView, SavedRouteCard,
FeaturedRouteCard, WarcraftLogsRunCard, MapLayersControl,
MapNoteEditor, …
navigation/ ExpansionMenu (sidebar), SearchBar (Ctrl+K), BreadcrumbNav
loot/ Loot rendering
ui/, dev/ Shared UI primitives and dev tools
src/layouts/
AppLayout.tsx Root layout with responsive sidebar/drawer + sticky header
MDT route encoding/decoding utilities live under src/lib/mdt/ (shared by both the editor and the raider.io scraper) and use pako for the LibCompress-compatible deflate step.
- Tailwind CSS 4 utilities
- Ant Design 6 components (cards, menus, tabs, tooltips, modals)
- Leaflet / react-leaflet for dungeon maps
- CSS custom properties in
src/theme/global.cssdefine the WoW-themed dark and light palettes - Ant Design theme tokens in
src/theme/tokens.ts - Responsive breakpoint at 768px
TypeScript types in src/types/ mirror the Blizzard API structure:
JournalExpansion→JournalInstance→JournalEncounter→JournalSection(recursive)JournalItemfor lootZoneSpellDatafor dungeon trash spells, NPC tiers, and interrupt flags- Enums:
Difficulty,ItemQuality,SectionHeaderIcon
- React 19 + TypeScript 6
- Vite 8 (build tool + dev server)
- React Router 7
- Ant Design 6
- Tailwind CSS 4
- Leaflet + react-leaflet (dungeon maps)
- pako (MDT route string deflate/inflate)
- Blizzard API, Raider.IO, and Warcraft Logs v2 API (build-time data sources)
Deployed on Vercel with SPA rewrite (vercel.json).