### Migration Example: Flat Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-migrate.md An example demonstrating how to use the `migrate` function to convert routes to the 'flat-files' convention. ```APIDOC ## Example: Migrate to Flat Files ```typescript import { migrate } from 'remix-flat-routes' migrate('routes', 'routes-flat', { convention: 'flat-files', force: false }) ``` **Output Example:** ``` ✓ Migrated routes/users/_layout.tsx → routes-flat/users._layout.tsx ✓ Migrated routes/users/$id.tsx → routes-flat/users.$id.tsx ``` ``` -------------------------------- ### Install remix-flat-routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/README.md Install the package using npm. ```bash npm install remix-flat-routes ``` -------------------------------- ### Basic createRoutesFromFolders Setup Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-createRoutesFromFolders.md Demonstrates the basic usage of createRoutesFromFolders with default app and routes directories. ```typescript import { defineRoutes } from 'remix-flat-routes' import { createRoutesFromFolders } from 'remix-flat-routes' const routes = createRoutesFromFolders(defineRoutes, { appDirectory: 'app', routesDirectory: 'routes' }) ``` -------------------------------- ### Migration Example: Hybrid with Force Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-migrate.md An example showing how to use the `migrate` function with the 'hybrid' convention and enabling the force overwrite option. ```APIDOC ## Example: Migrate to Hybrid with Force ```typescript migrate('routes', 'routes-hybrid', { convention: 'hybrid', force: true, ignoredRouteFiles: ['**/*.test.tsx', '**/.DS_Store'] }) ``` ``` -------------------------------- ### CLI Usage Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-migrate.md Demonstrates how to use the `migrate-flat-routes` CLI command with various options for different migration conventions and behaviors. ```APIDOC ## Example: CLI Usage The package includes a CLI command available as `migrate-flat-routes`: ```bash # Migrate to flat-files (default) migrate-flat-routes ./routes ./flat-routes # Migrate to flat-folders migrate-flat-routes ./routes ./flat-routes --convention=flat-folders # Migrate with force overwrite migrate-flat-routes ./routes ./flat-routes --force # Combine options migrate-flat-routes ./routes ./hybrid-routes --convention=hybrid --force ``` ``` -------------------------------- ### Directory Structure Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Shows a sample directory structure for the 'routes' folder demonstrating the hybrid convention with '+' suffixes for flat files. ```directory routes/ ├── _index/ │ └── index.tsx # / (index route) ├── _public+/ │ ├── _layout.tsx # Pathless layout │ ├── index.tsx # / │ ├── about.tsx # /about │ ├── contact[.jpg].tsx # /contact.jpg │ └── blog/ │ ├── index.tsx # /blog │ └── $slug.tsx # /blog/:slug ├── _auth+/ │ ├── login.tsx # /login │ ├── logout.tsx # /logout │ └── forgot-password.tsx # /forgot-password ├── users+/ │ ├── _layout.tsx # /users (pathless, contains children) │ ├── index.tsx # /users (index) │ ├── $userId.tsx # /users/:userId │ ├── $userId_.edit.tsx # /users/:userId/edit │ └── settings.tsx # /users/settings └── admin+/ ├── _layout.tsx ├── dashboard.tsx # /admin/dashboard └── users/ ├── index.tsx # /admin/users └── $id.tsx # /admin/users/:id ``` -------------------------------- ### Flat Files Route Structure Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md This example shows a typical file structure when using the flat-files convention for Remix routes. Each route is a distinct file within the 'routes/' directory. ```tree routes/ _auth.forgot-password.tsx _auth.login.tsx _auth.tsx _landing.about.tsx _landing.index.tsx _landing.tsx app.projects.tsx app.projects.$id.tsx app.tsx app_.projects.$id.roadmap.tsx ``` -------------------------------- ### Directory Structure Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Illustrates the file and directory organization for the flat routes convention, showing how to colocate assets like CSS and images with their respective routes. ```tree routes/ ├── __layout.tsx # Root layout ├── _index/ │ └── route.tsx # / (index route) ├── about/ │ └── route.tsx # /about ├── users/ │ ├── __layout.tsx # Pathless layout │ ├── _index/ │ │ └── route.tsx # /users (index) │ ├── $id/ │ │ ├── route.tsx # /users/:id │ │ ├── edit/ │ │ │ └── route.tsx # /users/:id/edit │ │ └── avatar.png # Colocated asset │ └── users.css # Colocated styles └── posts/ ├── route.tsx # /posts └── $id.tsx # /posts/:id ``` -------------------------------- ### Flat-Files Convention Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Shows how to use the '+' suffix on a folder name to treat it as a flat-file route, allowing nested structures within a flat convention. ```shell _auth+/forgot-password.tsx => _auth.forgot-password.tsx ``` ```shell ❯ tree app/routes-hybrid-files/ app/routes-hybrid-files/ ├── _auth+ │ ├── forgot-password.tsx │ └── login.tsx ├── _public+ │ ├── _layout.tsx │ ├── about.tsx │ ├── contact[.jpg].tsx │ └── index.tsx ├── project+ │ ├── _layout.tsx │ ├── parent.child │ │ └── index.tsx │ └── parent.child.grandchild │ ├── index.tsx │ └── styles.css └── users+ ├── $userId.tsx ├── $userId_.edit.tsx ├── _layout.tsx └── index.tsx ``` -------------------------------- ### Flat Routes File Structure Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Illustrates the file and folder structure used by the flat routes convention. Each file or folder corresponds to a route segment. ```directory routes/ _auth.forgot-password.tsx _auth.login.tsx _auth.reset-password.tsx _auth.signup.tsx _auth.tsx _landing.about.tsx _landing.index.tsx _landing.tsx app.calendar.$day.tsx app.calendar.index.tsx app.calendar.tsx app.projects.$id.tsx app.projects.tsx app.tsx app_.projects.$id.roadmap.tsx app_.projects.$id.roadmap[.pdf].tsx ``` -------------------------------- ### Tree-Shaking Support Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Illustrates how to import specific utilities from remix-flat-routes to leverage tree-shaking, ensuring only necessary code is bundled. ```typescript // Only imports flatRoutes and getRouteInfo // Other utilities are not bundled import flatRoutes, { getRouteInfo } from 'remix-flat-routes' ``` -------------------------------- ### Install Remix Flat Routes and React Router Adapter Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Install the necessary packages for using remix-flat-routes with React Router v7 support. This includes the adapter for converting Remix routes. ```bash npm install -D @react-router/remix-routes-option-adapter npm install -D remix-flat-routes ``` -------------------------------- ### RouteManifest Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/types.md An example of a RouteManifest object, showing how different routes are structured with their IDs, paths, file locations, parent IDs, and index properties. ```typescript { 'routes/index': { id: 'routes/index', path: '/', file: 'routes/index.tsx', parentId: 'root', index: true }, 'routes/users': { id: 'routes/users', path: '/users', file: 'routes/users.tsx', parentId: 'root' }, 'routes/users/$id': { id: 'routes/users/$id', path: '/users/:id', file: 'routes/users/$id.tsx', parentId: 'routes/users' } } ``` -------------------------------- ### Error Handling Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-migrate.md Illustrates how to handle potential errors during the migration process using a try-catch block. ```APIDOC ## Error Handling ```typescript try { migrate('routes', 'new-routes', { convention: 'flat-files' }) } catch (error) { if (error.message.includes('does not exist')) { console.error('Source directory not found') } else if (error.message.includes('already exists')) { console.error('Target directory exists; use force: true to overwrite') } else { console.error('Migration failed:', error.message) } } ``` ``` -------------------------------- ### DefineRoute Function Usage Examples Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/types.md Examples demonstrating how to use the defineRoute function for defining routes with different path patterns, file paths, and nested children. ```typescript defineRoute('/', 'routes/home.tsx') defineRoute('users/:id', 'routes/users/$id.tsx') defineRoute('users', 'routes/users/_layout.tsx', () => { defineRoute(':id', 'routes/users/$id.tsx') }) ``` -------------------------------- ### Flat Files Convention File Structure Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Illustrates a typical directory structure for the flat-files routing convention, showing how files map to different route segments and layouts. ```treeview routes/ ├── _layout.tsx # Root layout (/) ├── index.tsx # Index route (/) ├── about.tsx # /about ├── contact.tsx # /contact ├── blog.tsx # Pathless layout ├── blog.index.tsx # /blog ├── blog.$slug.tsx # /blog/:slug ├── blog.$slug.comments.tsx # /blog/:slug/comments ├── docs._layout.tsx # Pathless layout ├── docs.api.tsx # /docs/api ├── docs[.pdf].tsx # /docs.pdf (literal format) ├── files.$.tsx # /files/* (splat) └── search_.tsx # /search (with optional query) ``` -------------------------------- ### Flat Folders Route Structure Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md This example illustrates the flat-folders convention where each route is represented by a folder. The main route file is named 'index.tsx' within its respective folder. ```tree routes/ _auth/ index.tsx x <- route file (same as _auth.tsx) _auth.forgot-password/ index.tsx <- route file (same as _auth.forgot-password.tsx) _auth.login/ index.tsx <- route file (same as _auth.login.tsx) _landing.about/ index.tsx <- route file (same as _landing.about.tsx) employee-profile-card.tsx get-employee-data.server.tsx team-photo.jpg _landing.index/ index.tsx <- route file (same as _landing.index.tsx) scroll-experience.tsx _landing/ index.tsx <- route file (same as _landing.tsx) header.tsx footer.tsx app/ index.tsx <- route file (same as app.tsx) primary-nav.tsx footer.tsx app_.projects.$id.roadmap/ index.tsx <- route file (same as app_.projects.$id.roadmap.tsx) chart.tsx update-timeline.server.tsx app.projects/ index.tsx <- layout file (sames as app.projects.tsx) project-card.tsx get-projects.server.tsx project-buttons.tsx app.projects.$id/ index.tsx <- route file (sames as app.projects.$id.tsx) ``` -------------------------------- ### Name-Based Parent Matching Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/implementation-details.md Demonstrates how parent routes are identified by matching filename segments to build a route hierarchy. ```typescript // Given these files: app.tsx app.dashboard.tsx app.dashboard.$id.tsx // Segment matching: 'app' → parentId: undefined (top-level) 'app/dashboard' → parentId: 'app' (longest prefix match) 'app/dashboard/$id' → parentId: 'app/dashboard' (longest prefix match) ``` -------------------------------- ### Configure remix-flat-routes with Remix CLI Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Configure remix-flat-routes in your `remix.config.js` file. This example demonstrates how to ignore all files by default and then use `flatRoutes` to define your routes, excluding dot files. ```javascript const { flatRoutes } = require('remix-flat-routes') /** * @type {import("@remix-run/dev").AppConfig} */ module.exports = { // ignore all files in routes folder to prevent // default remix convention from picking up routes ignoredRouteFiles: ['**/*'], routes: async defineRoutes => { return flatRoutes('routes', defineRoutes, { ignoredRouteFiles: ['**/.*'], // Ignore dot files (like .DS_Store) //appDir: 'app', //routeDir: 'routes', //basePath: '/', //paramPrefixChar: '$', //nestedDirectoryChar: '+', //routeRegex: /((\${nestedDirectoryChar}[\/\\\\][^\/\\\:?*]+)|[\/\\]((index|route|layout|page)|(_[^\/\\\:?*]+)|([^\/\\\:?*]+\.route)))\.(ts|tsx|js|jsx|md|mdx)$$/, }) }, } ``` -------------------------------- ### Flat Files Convention Generated Routes Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Shows the resulting route objects generated by remix-flat-routes based on the flat-files convention, including path and ID properties. ```javascript _layout.tsx → { path: undefined, id: 'routes/_layout' } index.tsx → { path: '/', id: 'routes/index', index: true } about.tsx → { path: '/about', id: 'routes/about' } blog.tsx → { path: '/blog', id: 'routes/blog' } blog.index.tsx → { path: '/blog', id: 'routes/blog.index', index: true } blog.$slug.tsx → { path: '/blog/:slug', id: 'routes/blog.$slug' } blog.$slug.comments.tsx → { path: '/blog/:slug/comments', id: 'routes/blog.$slug.comments' } docs[.pdf].tsx → { path: '/docs.pdf', id: 'routes/docs[.pdf]' } files.$.tsx → { path: '/files/*', id: 'routes/files.$' } ``` -------------------------------- ### Route Definition Examples Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/README.md Illustrates both file-based and programmatic route definition methods. File-based uses `flatRoutes` to scan directories, while programmatic uses `defineRoutes` for explicit definitions. ```typescript // File-based flatRoutes('routes', defineRoutes) // Programmatic defineRoutes((route) => { route('/', 'routes/home.tsx') route('about', 'routes/about.tsx') }) ``` -------------------------------- ### CLI Success Console Output Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Example of the console output when the migration process completes successfully. It shows the convention used, source and target directories, ignored files, and a confirmation message. ```text 🛠️ Migrating to flat-routes using convention... 🗂️ source: 🗂️ target: 🙈ignored files: [array or undefined] 🏁 Finished! ``` -------------------------------- ### DefineRouteChildren Usage Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/types.md Demonstrates how to use the `DefineRouteChildren` callback to define nested routes using the `route()` function. ```typescript route('users', 'routes/users/_layout.tsx', () => { // This callback is DefineRouteChildren route('index', 'routes/users/index.tsx', { index: true }) route(':id', 'routes/users/$id.tsx') }) ``` -------------------------------- ### Generated Routes Example Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Lists the routes generated by Remix Flat Routes based on the provided directory structure and hybrid convention. ```text _index/index.tsx → { path: '/', id: 'routes/_index/index', index: true } _public+/_layout.tsx → { path: undefined, id: 'routes/_public+/_layout' } _public+/index.tsx → { path: '/', id: 'routes/_public+/index', index: true } _public+/about.tsx → { path: '/about', id: 'routes/_public+/about' } _auth+/login.tsx → { path: '/login', id: 'routes/_auth+/login' } users+/_layout.tsx → { path: '/users', id: 'routes/users+/_layout' } users+/index.tsx → { path: '/users', id: 'routes/users+/index', index: true } users+/$userId.tsx → { path: '/users/:userId', id: 'routes/users+/$userId' } users+/$userId_.edit.tsx → { path: '/users/:userId/edit', id: 'routes/users+/$userId_.edit' } admin+/dashboard.tsx → { path: '/admin/dashboard', id: 'routes/admin+/dashboard' } admin+/users/index.tsx → { path: '/admin/users', id: 'routes/admin+/users/index', index: true } ``` -------------------------------- ### Monorepo App Routes Setup Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Configure routes for the main application directory in a monorepo. Ensure the 'routes.ts' file is correctly placed within the app directory. ```typescript // packages/app/routes.ts import flatRoutes from 'remix-flat-routes' export default defineRoutes((route) => { flatRoutes('routes', route, { appDir: '.', }) }) ``` -------------------------------- ### Environment-Based Configuration for Remix Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Configure route generation based on the environment. This example uses `ignoredRouteFiles` to exclude development-specific files in production. ```typescript export default defineRoutes((route) => { const isDev = process.env.NODE_ENV === 'development' flatRoutes('routes', route, { appDir: 'app', ignoredRouteFiles: isDev ? [ '**/*.test.tsx', '**/*.stories.tsx', ] : [ '**/*.test.tsx', '**/*.stories.tsx', '**/*.dev.tsx', // Dev-only routes excluded in prod ], }) }) ``` -------------------------------- ### Migrate to Hybrid Convention with Force and Ignored Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-migrate.md This example demonstrates migrating routes to the hybrid convention, forcing overwrites if the target directory exists, and excluding specific test and system files using glob patterns. ```typescript migrate('routes', 'routes-hybrid', { convention: 'hybrid', force: true, ignoredRouteFiles: ['**/*.test.tsx', '**/.DS_Store'] }) ``` -------------------------------- ### Error Handling for createRoutesFromFolders Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-createRoutesFromFolders.md Provides an example of how to catch and handle potential errors thrown by createRoutesFromFolders, such as missing directories or route conflicts. ```typescript try { const routes = createRoutesFromFolders(defineRoutes, { routesDirectory: 'routes' }) } catch (error) { if (error.message.includes('Routes directory not found')) { console.error('Routes directory does not exist') } else if (error.message.includes('Invalid route module file')) { console.error('Non-route file found in routes directory') } else if (error.message.includes('conflicts with route')) { console.error('Duplicate route paths detected') } } ``` -------------------------------- ### React Router Routes from Flat Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Shows how the flat routes file structure is translated into React Router's and components. This demonstrates the declarative routing setup. ```jsx }> } /> } /> } /> } /> }> } /> } /> }> }> } /> } /> }> } /> } /> ``` -------------------------------- ### Migration to Flat Folders Convention Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Converts routes to the `flat-folders` convention, where each route is a folder containing a `route.tsx` file. This example demonstrates the transformation of a file-based route to a folder-based one. ```bash migrate-flat-routes ./routes ./routes-folders --convention=flat-folders ``` ```text users.$id.tsx ↓ users.$id/route.tsx ``` -------------------------------- ### Remix Config for Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Configure remix-flat-routes in remix.config.js to manage route generation and specify ignored route files. Requires 'remix-flat-routes' to be installed. ```javascript import { flatRoutes } from 'remix-flat-routes' export default { appDirectory: 'app', routes: async (defineRoutes) => { return flatRoutes('routes', defineRoutes, { ignoredRouteFiles: ['**/*.test.tsx', '**/.DS_Store'], }) }, } ``` -------------------------------- ### Custom File Visitor for Remix Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Implement custom directory traversal logic by providing a `visitFiles` function. This example shows a cached visitor to optimize file system reads. ```typescript import { flatRoutes, type VisitFilesFunction } from 'remix-flat-routes' import * as fs from 'fs' import * as path from 'path' const cachedVisitor: VisitFilesFunction = (() => { const cache = new Map() return (dir, visitor, baseDir = dir) => { if (!cache.has(dir)) { const files: string[] = [] for (const file of fs.readdirSync(dir)) { const fullPath = path.resolve(dir, file) const stat = fs.lstatSync(fullPath) if (stat.isDirectory()) { cachedVisitor(fullPath, visitor, baseDir) } else if (stat.isFile()) { const relative = path.relative(baseDir, fullPath) files.push(relative) visitor(relative) } } cache.set(dir, files) } else { for (const file of cache.get(dir)!) { visitor(file) } } } })() export default defineRoutes((route) => { flatRoutes('routes', route, { visitFiles: cachedVisitor, }) }) ``` -------------------------------- ### Custom File Visitor with Caching Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/implementation-details.md An example of a custom file visitor that implements caching to memoize directory scans. It stores visited files and reuses the cache on subsequent calls. ```typescript const cachedVisitor = (() => { const cache = new Map() return (dir, visitor, baseDir = dir) => { if (cache.has(dir)) { cache.get(dir).forEach(file => visitor(file)) } else { const files = [] defaultVisitFiles(dir, (file) => { files.push(file) visitor(file) }, baseDir) cache.set(dir, files) } } })() ``` -------------------------------- ### CLI Error Console Output: Source Directory Not Found Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Example of console output when the specified source directory for migration does not exist. The CLI cannot proceed if the source path is invalid. ```text source directory '' does not exist ``` -------------------------------- ### CLI Error Console Output: Source and Target Same Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Example of console output when the source and target directories provided for migration are identical. The CLI requires distinct source and target paths to prevent accidental data loss. ```text source and target directories must be different ``` -------------------------------- ### CLI Error Console Output: Target Exists Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Example of console output when the target directory already exists and the --force flag is not provided. This indicates that the migration cannot proceed without explicit permission to overwrite. ```text ❌ target directory '' already exists use --force to overwrite ``` -------------------------------- ### Importing Default and Named Exports Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Example of how to import the default `flatRoutes` function along with several named exports like `getRouteInfo`, `createRoutePath`, `isIndexRoute`, and types such as `FlatRoutesOptions` and `RouteManifest` from the 'remix-flat-routes' package. ```typescript import flatRoutes, { getRouteInfo, createRoutePath, isIndexRoute, type FlatRoutesOptions, type RouteManifest } from 'remix-flat-routes' ``` -------------------------------- ### Configure Routes with React Router v7 Adapter Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Configure your routes in `app/routes.ts` to use the remix-flat-routes convention with the React Router v7 adapter. This example shows basic setup and common configuration options. ```typescript // app/routes.ts import { remixRoutesOptionAdapter } from "@react-router/remix-routes-option-adapter"; import { flatRoutes } from "remix-flat-routes"; export default remixRoutesOptionAdapter((defineRoutes) => { return flatRoutes("routes", defineRoutes, { ignoredRouteFiles: ['**/.*'], // Ignore dot files (like .DS_Store) //appDir: 'app', //routeDir: 'routes', //basePath: '/', //paramPrefixChar: '$', //nestedDirectoryChar: '+', //routeRegex: /((\${nestedDirectoryChar}[\/\\\\][^\/\\\:?*]+)|[\/\\\\]((index|route|layout|page)|(_[^\/\\\:?*]+)|([^\/\\\:?*]+\.route)))\.(ts|tsx|js|jsx|md|mdx)$$/, }); }); ``` -------------------------------- ### CLI Usage Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Demonstrates how to execute the migrate-flat-routes command from the command line. ```bash migrate-flat-routes command ``` -------------------------------- ### Basic Migration to Flat Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Migrates routes from a specified source directory to a target directory using the default `flat-files` convention. The output shows the migration progress and a summary of transformed files. ```bash migrate-flat-routes ./app/routes ./app/routes-flat ``` ```text 🛠️ Migrating to flat-routes using flat-files convention... 🗂️ source: ./app/routes 🗂️ target: ./app/routes-flat 🙈ignored files: undefined ✓ Migrated users/_layout.tsx → users._layout.tsx ✓ Migrated users/index.tsx → users._index.tsx ✓ Migrated users/$id.tsx → users.$id.tsx ✓ Migrated posts/route.tsx → posts.tsx 🏁 Finished! ``` -------------------------------- ### Configuring Ignored Route Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/README.md Example of how to configure `ignoredRouteFiles` in `remix.config.js` to prevent certain files from being treated as routes. ```javascript // remix.config.js export default { ignoredRouteFiles: ['**/*.test.tsx', '**/.DS_Store'], // other config } ``` -------------------------------- ### Import All Types and Functions Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Demonstrates how to import all necessary components from the 'remix-flat-routes' library, including migration functions and type definitions. ```typescript import { migrate, convertToRoute, type MigrateOptions, type RoutingConvention } from 'remix-flat-routes' ``` -------------------------------- ### Migration with Relative Paths Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Demonstrates using relative paths for source and target directories. The leading `./` is optional, and paths are resolved relative to the current working directory. ```bash migrate-flat-routes routes new-routes --convention=flat-files ``` -------------------------------- ### Configure createRoutesFromFolders Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/configuration.md Set up route creation from folders with options for app directory, routes directory, and ignored file patterns. ```typescript createRoutesFromFolders(defineRoutes, { appDirectory: 'app', routesDirectory: 'routes', ignoredFilePatterns: [] }) ``` -------------------------------- ### Migration with Multiple Options Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Shows how to combine multiple options, such as `--convention` and `--force`, for route migration. The order of options does not affect the outcome. ```bash migrate-flat-routes ./source ./target --convention=hybrid --force ``` -------------------------------- ### Parameter Validation Syntax Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/implementation-details.md Shows the correct and incorrect syntax for defining route parameters. Parameter names must start with a '$' symbol. ```typescript // ❌ Invalid - $ in middle id$value // Error: must start with $ // ✅ Valid $id // Dynamic: /:id ($id) // Optional: /:id? $ // Splat: /* ``` -------------------------------- ### Identifying Server-Only Companion Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Explains how files containing '.server.' are recognized as companion files and not treated as routes. ```text users.tsx # Route file users.server.tsx # NOT a route (companion) users.server.ts # NOT a route (companion) users.$id.tsx # Route file users.$id.server.tsx # NOT a route (companion) ``` -------------------------------- ### CLI Usage for Route Migration Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-migrate.md These commands show how to use the `migrate-flat-routes` CLI for various migration scenarios, including specifying conventions, forcing overwrites, and combining options. ```bash # Migrate to flat-files (default) migrate-flat-routes ./routes ./flat-routes # Migrate to flat-folders migrate-flat-routes ./routes ./flat-routes --convention=flat-folders # Migrate with force overwrite migrate-flat-routes ./routes ./flat-routes --force # Combine options migrate-flat-routes ./routes ./hybrid-routes --convention=hybrid --force ``` -------------------------------- ### Migrating Flat Folders to Flat Files Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Demonstrates the file renaming convention when converting from a flat-folders structure back to a flat-files structure. ```text users/_layout/route.tsx → users._layout.tsx users/$id/route.tsx → users.$id.tsx users/edit/route.tsx → users.edit.tsx ``` -------------------------------- ### Directory Structure: Hybrid Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Demonstrates the directory structure for hybrid routes, enabling nested folders while maintaining colocation and flat route principles. ```shell ❯ tree app/routes-hybrid app/routes-hybrid ├── _index │ └── index.tsx ├── _public │ ├── _layout.tsx │ ├── about │ │ └── _route.tsx │ └── contact[.jpg] │ └── _route.tsx ├── test.$ │ └── _route.tsx └── users ├── $userId │ ├── _route.tsx │ └── avatar.png ├── $userId_.edit │ └── _route.tsx ├── _index │ └── index.tsx ├── _layout.tsx └── users.css ``` -------------------------------- ### Full Option Set for flatRoutes() Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/configuration.md Demonstrates the complete set of configuration options available when initializing flatRoutes. Ensure all paths and characters are correctly defined for your project structure. ```typescript flatRoutes(routeDir, defineRoutes, { appDir: 'app', routeDir: 'routes', basePath: '/', paramPrefixChar: '$', nestedDirectoryChar: '+', ignoredRouteFiles: [], visitFiles: defaultVisitFiles, routeRegex: defaultRegex }) ``` -------------------------------- ### Experimental Migration (Preserve Original) Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Perform a migration to a temporary directory to review changes before committing. If unsatisfied, the experimental directory can be safely removed. ```bash # Try migration to a temporary directory migrate-flat-routes ./app/routes ./app/routes-experimental --convention=hybrid # Review the results # If satisfied, you can rename or delete the original # If not satisfied, delete experimental and try again rm -rf ./app/routes-experimental migrate-flat-routes ./app/routes ./app/routes-experimental --convention=flat-files ``` -------------------------------- ### React Router v7 Integration with Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Integrate flatRoutes with React Router v7 using the official adapter. This setup requires '@react-router/remix-routes-option-adapter' and 'remix-flat-routes'. ```typescript import { remixRoutesOptionAdapter } from '@react-router/remix-routes-option-adapter' import { flatRoutes } from 'remix-flat-routes' export default remixRoutesOptionAdapter((defineRoutes) => { return flatRoutes('routes', defineRoutes, { ignoredRouteFiles: ['**/.*'], }) }) ``` -------------------------------- ### Provide Required Arguments for migrate-flat-routes CLI Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/errors.md The `migrate-flat-routes` CLI requires at least two positional arguments: the source and target directories. Failing to provide these will result in an exit code of 1 due to missing arguments. ```bash # ❌ WRONG - missing target migrate-flat-routes ./routes # ❌ WRONG - no arguments migrate-flat-routes # ✅ CORRECT migrate-flat-routes ./routes ./routes-flat ``` -------------------------------- ### Monorepo Admin Routes Setup Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Configure routes for an admin section in a monorepo, specifying a 'basePath' to prefix all admin routes. Ensure the 'routes.ts' file is in the admin directory. ```typescript // packages/admin/routes.ts import flatRoutes from 'remix-flat-routes' export default defineRoutes((route) => { flatRoutes('routes', route, { appDir: '.', basePath: '/admin', }) }) ``` -------------------------------- ### Standard Remix v2 Route Definition Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/integration-patterns.md Define routes using flatRoutes within a routes configuration file for standard Remix v2 integration. Ensure 'remix-flat-routes' is installed. ```typescript import { flatRoutes } from 'remix-flat-routes' import { defineRoutes } from 'remix-flat-routes' export default defineRoutes((route) => { flatRoutes('routes', route) }) ``` -------------------------------- ### Migrating Flat Files to Flat Folders Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Illustrates the file renaming convention when converting from a flat-files structure to a flat-folders structure. ```text users._layout.tsx → users/_layout/route.tsx users.$id.tsx → users.$id/route.tsx users.$id.edit.tsx → users.$id.edit/route.tsx ``` -------------------------------- ### Migrate Routes with Verified Path Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Attempt route migration again after verifying the source path is correct. ```bash migrate-flat-routes ./app/routes ./app/routes-migrated ``` -------------------------------- ### Configure remix-flat-routes with Vite Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Integrate remix-flat-routes into your Vite configuration by updating the `routes` option in `vite.config.ts`. This example shows how to use `flatRoutes` to define your routes, ignoring dot files. ```typescript import { vitePlugin as remix } from '@remix-run/dev' import { defineConfig } from 'vite' import tsconfigPaths from 'vite-tsconfig-paths' import { flatRoutes } from 'remix-flat-routes' export default defineConfig({ plugins: [ remix({ routes(defineRoutes) { return flatRoutes('routes', defineRoutes, { ignoredRouteFiles: ['**/.*'], // Ignore dot files (like .DS_Store) //appDir: 'app', //routeDir: 'routes', //basePath: '/', //paramPrefixChar: '$', //nestedDirectoryChar: '+', //routeRegex: /((\${nestedDirectoryChar}[\/\\\\][^\/\\\:?*]+)|[\/\\]((index|route|layout|page)|(_[^\/\\\:?*]+)|([^\/\\\:?*]+\.route)))\.(ts|tsx|js|jsx|md|mdx)$$/, }) }, }), tsconfigPaths(), // ... ] }) ``` -------------------------------- ### Customizing App and Routes Directories Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/api-reference-createRoutesFromFolders.md Shows how to configure createRoutesFromFolders to look for routes in custom directories. ```typescript const routes = createRoutesFromFolders(defineRoutes, { appDirectory: 'src', routesDirectory: 'pages' }) // Looks for routes in: src/pages/ ``` -------------------------------- ### Source File Structure Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Illustrates the directory structure of the remix-flat-routes project, showing the location of key files. ```treeview src/ ├── index.ts (main entry, flatRoutes, utilities) ├── routes.ts (defineRoutes, core types) ├── lib.ts (createRoutesFromFolders, path utilities) ├── migrate.ts (migration functionality) └── cli.ts (CLI command entry point) ``` -------------------------------- ### Verify Source Directory Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Before migrating, verify the source directory exists using standard shell commands. ```bash pwd ``` ```bash ls -la ``` -------------------------------- ### Use Valid Options with migrate-flat-routes CLI Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/errors.md Ensure all command-line options passed to `migrate-flat-routes` are valid. Providing unknown options, such as `--invalid=option`, will trigger a usage error. ```bash # ❌ WRONG - invalid option migrate-flat-routes ./routes ./target --invalid=option # ✅ CORRECT migrate-flat-routes ./routes ./target --convention=flat-files --force ``` -------------------------------- ### Migration to Hybrid Convention with Force Overwrite Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Migrates routes to the `hybrid` convention and forces an overwrite of the target directory if it already exists. The example shows transformations for nested routes and layout files. ```bash migrate-flat-routes ./app/routes ./app/routes-hybrid --convention=hybrid --force ``` ```text users/index.tsx users/$id.tsx ↓ users+/index.tsx users+/$id.tsx ``` -------------------------------- ### Correct Route Parameter Syntax in Remix Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/errors.md Ensure dynamic route parameters start with the defined prefix character (default: '$'). Incorrect syntax can lead to errors when the router attempts to parse parameters. ```typescript // ❌ WRONG with default $ prefix post.$id.comment$id.tsx // Second $id doesn't start the segment // ✅ CORRECT post.$id.comments.$commentId.tsx // Each parameter starts with $ ``` -------------------------------- ### Remix Flat Routes Utilities for Testing Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Imports and demonstrates the usage of several individual utility functions from `remix-flat-routes` for testing purposes, such as `getRouteSegments` and `createRoutePath`. ```typescript import { isRouteModuleFile, isIndexRoute, getRouteInfo, createRoutePath, getRouteSegments, createRouteId, normalizeSlashes, defaultVisitFiles, type FlatRoutesOptions } from 'remix-flat-routes' // Test individual utilities const segments = getRouteSegments('users.$id', false, '$', '+') const path = createRoutePath(segments, false, { paramPrefixChar: '$' }) ``` -------------------------------- ### Directory Structure: Default Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/README.md Illustrates the directory structure for default flat routes in Remix v2, where folder names directly map to route paths. ```shell ❯ tree app/routes-folders app/routes-folders ├── _index │ └── page.tsx ├── _public │ └── _layout.tsx ├── _public.about │ └── index.tsx ├── _public.contact[.jpg] │ └── index.tsx ├── test.$ │ ├── _route.server.tsx │ └── _route.tsx ├── users │ ├── _layout.tsx │ └── users.css ├── users.$userId │ ├── _route.tsx │ └── avatar.png ├── users.$userId_.edit │ └── _route.tsx └── users._index └── index.tsx ``` -------------------------------- ### Windows Compatibility Configuration Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/configuration.md Adjusts the nested directory character for Windows compatibility to avoid conflicts with reserved characters like '+', which is used by Vercel. This example shows using '~' instead and notes the required folder name update. ```typescript flatRoutes('routes', defineRoutes, { nestedDirectoryChar: '~' // Instead of + which Vercel reserves }) // Update folder names: _public~/ instead of _public+/ ``` -------------------------------- ### Get Parent Route IDs with Map Optimization Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/implementation-details.md Calculates parent route IDs for a given list of route IDs using a Map for efficient O(1) lookups. It iterates through potential parent IDs to find the longest matching segment prefix. ```typescript function getParentRouteIds(routeIds) { const routeIdMap = new Map(routeIds.map(id => [id, id])) const parentMap = new Map() for (const [childId] of routeIdMap) { let parentId = undefined // Find longest matching parent for (const [potentialParentId] of routeIdMap) { if (childId.startsWith(`${potentialParentId}/`)) { parentId = potentialParentId break } } parentMap.set(childId, parentId) } return Object.fromEntries(parentMap) } ``` -------------------------------- ### Configure migrate() Utility Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/configuration.md Set migration options including convention, force overwrite, and ignored route files. ```typescript migrate(sourceDir, targetDir, { convention: 'flat-files', force: false, ignoredRouteFiles: [] }) ``` -------------------------------- ### Using Multiple Remix Flat Routes Modules Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Illustrates importing and using various functions from `remix-flat-routes` simultaneously, including different route generation methods and the `migrate` function. ```typescript import flatRoutes, { isIndexRoute, getRouteInfo } from 'remix-flat-routes' import { defineRoutes } from 'remix-flat-routes' import { createRoutesFromFolders } from 'remix-flat-routes' import { migrate } from 'remix-flat-routes' // Use different route generation approaches const flatRoutes = flatRoutes('routes', defineRoutes) const folderRoutes = createRoutesFromFolders(defineRoutes) // Migrate between conventions migrate('./old-routes', './new-routes', { convention: 'flat-files' }) ``` -------------------------------- ### Configuration Merging Order Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/implementation-details.md Illustrates the layering of configuration options, from default settings to explicitly provided ones, with explicit options taking the highest priority. ```typescript const options = { ...defaultOptions, // Layer 1: Defaults ...loadRemixConfig(), // Layer 2: Config file ...providedOptions // Layer 3: Explicit } ``` -------------------------------- ### Hybrid Convention Naming Rules Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/conventions.md Illustrates how file and folder naming patterns map to route paths when using the '+' suffix for flat files within nested structures. ```markdown | Pattern | |---------| | `folder+/file.tsx` | Maps To | Example | |---------|---------| | `folder+/file.tsx` | `/file` | `/routes/_auth+/login.tsx` → `/login` | | `folder+/_layout.tsx` | Pathless layout | `/routes/_public+/_layout.tsx` | | `folder+/parent.child.tsx` | `/parent/child` | `/routes/api+/users.posts.tsx` → `/users/posts` | | `folder+/$param.tsx` | `/:param` | `/routes/_admin+/$id.tsx` → `/:id` | | `folder+/nested/child.tsx` | `/nested/child` | `/routes/app+/dashboard/index.tsx` → `/dashboard` | ``` -------------------------------- ### Configure Route Directories (Multiple) Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/configuration.md Define multiple directories for route files to organize routes by domain or area. This allows for a more structured project layout. ```typescript routeDir: ['routes', 'admin-routes', 'api-routes'] ``` -------------------------------- ### Package.json Entry Points Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Defines the entry points for the remix-flat-routes package in package.json, specifying formats for CommonJS, ESM, and the CLI. ```json { "main": "dist/index.cjs", "module": "dist/index.js", "types": "dist/index.d.ts", "bin": { "migrate-flat-routes": "dist/cli.cjs" } } ``` -------------------------------- ### Run npm Migration Scripts Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md Execute the migration commands defined in package.json using npm run. This is a convenient way to trigger the migration process. ```bash npm run migrate:flat-files npm run migrate:hybrid ``` -------------------------------- ### Migration Tool for Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/README.md Use the `migrate-flat-routes` command to convert existing Remix routes to the flat-routes convention. This tool helps in migrating your route structure. ```bash npm install -D remix-flat-routes migrate-flat-routes ./routes ./routes-flat --convention=flat-files ``` -------------------------------- ### Batch Migration for Multiple Projects Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/cli-reference.md A bash script to automate the migration process across multiple projects. It iterates through a list of projects, applying the migration command to each. ```bash #!/bin/bash # Script to migrate multiple route directories for project in project1 project2 project3; do echo "Migrating $project..." migrate-flat-routes \ "./packages/$project/routes" \ "./packages/$project/routes-migrated" \ --convention=hybrid \ --force done echo "All migrations complete!" ``` -------------------------------- ### Importing Remix Flat Routes Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Shows how to import the remix-flat-routes package using CommonJS and ESM module systems. ```javascript // CommonJS: const flatRoutes = require('remix-flat-routes') // ESM: import flatRoutes from 'remix-flat-routes' ``` -------------------------------- ### Import Remix Flat Routes Folder Utilities Source: https://github.com/kiliman/remix-flat-routes/blob/main/_autodocs/module-exports.md Imports utility functions and types for creating routes from folder structures in 'remix-flat-routes'. ```typescript import { createRoutesFromFolders, createRoutePath, type CreateRoutesFromFoldersOptions } from 'remix-flat-routes' ```