Created
July 23, 2025 08:48
-
-
Save trinhvanminh/17bbe8ea79461571a60bd5b1ff9c5642 to your computer and use it in GitHub Desktop.
Nextjs app router -> generate routes scripts (not handle dynamic route yet)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // generateRoutes.js | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| // the app folder path | |
| const appDir = path.join(__dirname, 'src/app'); | |
| // the output path | |
| const routeFile = path.join(__dirname, 'src/routes.ts'); | |
| function toCamelCase(str) { | |
| return str | |
| .replace(/[^a-zA-Z0-9]/g, ' ') | |
| .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (index === 0 ? word.toLowerCase() : word.toUpperCase())) | |
| .replace(/\s+/g, ''); | |
| } | |
| function walk(dir, prefix = '') { | |
| const routes = {}; | |
| const files = fs.readdirSync(dir); | |
| for (const file of files) { | |
| const fullPath = path.join(dir, file); | |
| const relativePath = path.relative(appDir, fullPath); | |
| const stat = fs.statSync(fullPath); | |
| if (stat.isDirectory()) { | |
| const hasPageFile = fs.readdirSync(fullPath).some((f) => f.startsWith('page.') && !f.startsWith('_')); | |
| if (hasPageFile) { | |
| const urlPath = '/' + relativePath.replace(/\\/g, '/'); | |
| // TODO: Handle dynamic routes | |
| // // Generate function name for dynamic routes | |
| // function generateDynamicRouteName(path, params) { | |
| // const segments = path.split('/').filter(Boolean); | |
| // let nameParts = ['get']; | |
| // segments.forEach((segment) => { | |
| // if (segment.startsWith('${') && segment.endsWith('}')) { | |
| // const param = segment.slice(2, -1); // Extract param from ${param} | |
| // nameParts.push(capitalize(param)); | |
| // } else { | |
| // nameParts.push(capitalize(sanitizeSegment(segment))); | |
| // } | |
| // }); | |
| // nameParts.push('Route'); | |
| // return nameParts.join(''); | |
| // } | |
| // routePath = urlPath.replace(`[${param}]`, `\${${param}}`); | |
| // const functionName = generateDynamicRouteName(routePath, params); | |
| // const paramsString = params.join(', '); | |
| // routesCode += `export const ${functionName} = (${paramsString}) => \`${routePath}\`;\n`; | |
| const key = toCamelCase(relativePath.replace(/\/page.*$/, '')); | |
| routes[key] = urlPath; | |
| } | |
| const subRoutes = walk(fullPath, prefix + file + '/'); | |
| Object.assign(routes, subRoutes); | |
| } | |
| } | |
| return routes; | |
| } | |
| const routes = walk(appDir); | |
| let fileContent = `// Auto-generated by generateRoutes.js\n\nexport const ROUTES = {\n`; | |
| for (const [key, value] of Object.entries(routes)) { | |
| fileContent += ` ${key}: '${value}',\n`; | |
| } | |
| fileContent += `};\n`; | |
| fs.writeFileSync(routeFile, fileContent); | |
| console.log(`✅ Route file generated at ${routeFile}`); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Auto-generated by generateRoutes.js | |
| export const ROUTES = { | |
| AuthCheckMail: '/(auth)/check-mail', | |
| AuthForgetPass: '/(auth)/forget-pass', | |
| AuthLogin: '/(auth)/login', | |
| AuthRegister: '/(auth)/register', | |
| AuthResetPass: '/(auth)/reset-pass', | |
| AuthVerifyCode: '/(auth)/verify-code', | |
| hostAdministrationIdentityUsers: '/host/(administration)/identity/users', | |
| hostDashboardAnalytics: '/host/dashboard/analytics', | |
| hostDashboardDefault: '/host/dashboard/default', | |
| hostSamplePage: '/host/sample-page', | |
| hostDtAdministrationIdentityUsers: '/host-dt/(administration)/identity/users', | |
| hostDtDashboardDefault: '/host-dt/dashboard/default', | |
| hostDtGeneralManagementRelationship: '/host-dt/general-management/relationship', | |
| hostDtGeneralManagementWarehouseList: '/host-dt/general-management/warehouse-list', | |
| hostDtGeneralManagementWhUserList: '/host-dt/general-management/wh-user-list', | |
| hostDtRequestManagementManuAccess: '/host-dt/request-management/manu-access', | |
| hostDtRequestManagementOnboardWhUsers: '/host-dt/request-management/onboard-wh-users', | |
| hostDtRequestManagementOnboardWhUsersCreateOnboardWhUsers: '/host-dt/request-management/onboard-wh-users/create-onboard-wh-users', | |
| hostDtRequestManagementOnboardWhUsersIdEditOnboardWhUserRequest: '/host-dt/request-management/onboard-wh-users/[id]/edit-onboard-wh-user-request', | |
| hostDtRequestManagementOnboardWhUsersIdOnboardWhUsersDetail: '/host-dt/request-management/onboard-wh-users/[id]/onboard-wh-users-detail', | |
| hostDtSamplePage: '/host-dt/sample-page', | |
| manuAdministrationIdentityUsers: '/manu/(administration)/identity/users', | |
| manuDashboardAnalytics: '/manu/dashboard/analytics', | |
| manuDashboardDefault: '/manu/dashboard/default', | |
| manuSamplePage: '/manu/sample-page', | |
| pages500: '/pages/500', | |
| pagesComingSoon: '/pages/coming-soon', | |
| pagesLanding: '/pages/landing', | |
| pagesUnderConstruction: '/pages/under-construction', | |
| whUsersAdministrationIdentityUsers: '/wh-users/(administration)/identity/users', | |
| whUsersDashboardAnalytics: '/wh-users/dashboard/analytics', | |
| whUsersDashboardDefault: '/wh-users/dashboard/default', | |
| whUsersSamplePage: '/wh-users/sample-page', | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment