Skip to content

Instantly share code, notes, and snippets.

@trinhvanminh
Created July 23, 2025 08:48
Show Gist options
  • Select an option

  • Save trinhvanminh/17bbe8ea79461571a60bd5b1ff9c5642 to your computer and use it in GitHub Desktop.

Select an option

Save trinhvanminh/17bbe8ea79461571a60bd5b1ff9c5642 to your computer and use it in GitHub Desktop.
Nextjs app router -> generate routes scripts (not handle dynamic route yet)
// 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}`);
// 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