- Add 'use client' directives to all remaining components
- Update imports from next/router to next/navigation
- Replace router.locale with getCookie('NEXT_LOCALE')
- Update LanguageSwitch to use router.refresh()
- Replace router.asPath with usePathname()
Components migrated:
- Common: SelectWithInput, Editor
- Layout: Header, Layout, MentionList, ElementToggle
- Misc: UpdateToast, SearchModal, RaidCombobox, FilterModal
- Misc: ChangelogUnit, HovercardHeader, LanguageSwitch
- Extra: GuidebookUnit, GuidebookResult
- Reps: GridRep, CharacterRep, WeaponRep, SummonRep
Added migration PRD documentation to track progress.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
6.9 KiB
6.9 KiB
App Router Migration PRD
Overview
Complete migration from Next.js Pages Router to App Router by updating all components to use next/navigation instead of next/router.
Migration Requirements
Router API Changes
useRouter()fromnext/router→useRouter()fromnext/navigationrouter.query→useSearchParams()hookrouter.pathname→usePathname()hookrouter.asPath→ combination ofusePathname()+useSearchParams()router.push()→ stays the samerouter.replace()→ stays the samerouter.back()→ stays the samerouter.reload()→router.refresh()router.prefetch()→ stays the samerouter.beforePopState()→ not available in App Router (needs alternative)router.events→ not available in App Router (needs alternative)
Import Updates Required
All imports need to change from:
import { useRouter } from 'next/router'
To:
import { useRouter, usePathname, useSearchParams } from 'next/navigation'
Files to Migrate
App Directory Files (Already using next/navigation - 6 files)
These files already use next/navigation but should be verified:
/app/teams/TeamsPageClient.tsx/app/saved/SavedPageClient.tsx/app/p/[party]/PartyPageClient.tsx/app/new/NewPartyClient.tsx/app/components/Header.tsx/app/[username]/ProfilePageClient.tsx
Pages Directory Files (1 file)
/pages/about.tsx- Needs migration to app router or update imports
Component Files - Auth (3 files)
/components/auth/LoginModal/index.tsx/components/auth/SignupModal/index.tsx/components/auth/AccountModal/index.tsx
Component Files - Character (5 files)
/components/character/CharacterUnit/index.tsx/components/character/CharacterModal/index.tsx/components/character/CharacterHovercard/index.tsx/components/character/CharacterConflictModal/index.tsx/components/character/CharacterResult/index.tsx
Component Files - Weapon (7 files)
/components/weapon/WeaponUnit/index.tsx/components/weapon/WeaponModal/index.tsx/components/weapon/WeaponKeySelect/index.tsx/components/weapon/WeaponHovercard/index.tsx/components/weapon/WeaponConflictModal/index.tsx/components/weapon/WeaponResult/index.tsx/components/weapon/WeaponLabelIcon/index.tsx
Component Files - Summon (3 files)
/components/summon/SummonUnit/index.tsx/components/summon/SummonHovercard/index.tsx/components/summon/SummonResult/index.tsx
Component Files - Party (5 files)
/components/party/PartyHeader/index.tsx/components/party/PartyHead/index.tsx/components/party/PartyFooter/index.tsx/components/party/PartyDropdown/index.tsx/components/party/Party/index.tsx
Component Files - Job (7 files)
/components/job/JobSkillItem/index.tsx/components/job/JobSection/index.tsx/components/job/JobDropdown/index.tsx/components/job/JobAccessoryPopover/index.tsx/components/job/JobAccessoryItem/index.tsx/components/job/JobSkillResult/index.tsx/components/job/JobImage/index.tsx
Component Files - Mastery (3 files)
/components/mastery/ExtendedMasterySelect/index.tsx/components/mastery/AxSelect/index.tsx/components/mastery/AwakeningSelectWithInput/index.tsx
Component Files - Reps (4 files)
/components/reps/GridRep/index.tsx/components/reps/CharacterRep/index.tsx/components/reps/WeaponRep/index.tsx/components/reps/SummonRep/index.tsx
Component Files - Common (2 files)
/components/common/SelectWithInput/index.tsx/components/common/Editor/index.tsx
Component Files - Extra (2 files)
/components/extra/GuidebookUnit/index.tsx/components/extra/GuidebookResult/index.tsx
Component Files - Other (11 files)
/components/toasts/UpdateToast/index.tsx/components/search/SearchModal/index.tsx/components/raids/RaidCombobox/index.tsx/components/filters/FilterModal/index.tsx/components/MentionList/index.tsx/components/Layout/index.tsx/components/LanguageSwitch/index.tsx/components/Header/index.tsx/components/ElementToggle/index.tsx/components/about/ChangelogUnit/index.tsx/components/HovercardHeader/index.tsx
Utility Files (1 file)
/utils/changeLanguage.tsx
Total Files to Migrate: 59
Migration Steps for Each File
-
Analyze current usage
- Check how
routeris being used - Identify which properties/methods are accessed
- Note any router.events listeners
- Check how
-
Update imports
- Change from
next/routertonext/navigation - Add additional hooks if needed (
usePathname,useSearchParams)
- Change from
-
Update router usage
- Replace
router.querywithuseSearchParams() - Replace
router.pathnamewithusePathname() - Update any other router property access
- Replace
-
Handle edge cases
- Router events (need alternative approach)
- beforePopState (need alternative approach)
- Dynamic route params (use
useParams())
-
Test the component
- Ensure navigation still works
- Check query parameter handling
- Verify dynamic routes
Special Considerations
Router Events
Files using router.events will need special handling as this is not available in App Router. Common patterns:
- Route change start/complete events → Use loading.tsx or Suspense
- Route change error → Use error boundaries
Query Parameters
When migrating router.query:
// Old (Pages Router)
const { id, filter } = router.query
// New (App Router)
const searchParams = useSearchParams()
const id = searchParams.get('id')
const filter = searchParams.get('filter')
Dynamic Route Parameters
For dynamic segments like [id]:
// Old (Pages Router)
const { id } = router.query
// New (App Router)
import { useParams } from 'next/navigation'
const params = useParams()
const id = params.id
Programmatic Navigation
// Both routers (mostly the same)
router.push('/path')
router.replace('/path')
router.back()
// Refresh (different)
// Old: router.reload()
// New: router.refresh()
Post-Migration Cleanup
After all files are migrated:
- Remove
/pagesdirectory (except/pages/apiif still needed) - Remove Pages Router specific configuration
- Update
_app.tsxdependencies if any remain - Test all routes thoroughly
- Update any documentation
Success Criteria
- All components use
next/navigationimports - No references to
next/routerremain in components (only in pages/about.tsx which still needs migration) - All navigation functionality works as before
- No console errors about "NextRouter was not mounted"
- App runs successfully with
npm run dev - Build completes with
npm run build(to be tested)