Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

remix-flat-routes

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

remix-flat-routes

Package for generating routes using flat convention

  • 0.4.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
71K
decreased by-4.16%
Maintainers
1
Weekly downloads
 
Created
Source

Remix Flat Routes

All Contributors

This package enables you to define your routes using the flat-routes convention. This is based on the gist by Ryan Florence

🛠 Installation

npm install remix-flat-routes

⚙️ Configuration

Update your remix.config.js file and use the custom routes config option.

const { flatRoutes } = require('remix-flat-routes')
module.exports = {
  // ignore all files in routes folder
  ignoredRouteFiles: ['**/*'],
  routes: async defineRoutes => {
    return flatRoutes('routes', defineRoutes)
  },
}

NOTE: basePath should be relative to the app folder. If you want to use the routes folder, you will need to update the ignoreRouteFiles property to ignore all files: **/*

🚚 Migrating Existing Routes

You can now migrate your existing routes to the new flat-routes convention. Simply run:

npx migrate-flat-routes <sourceDir> <targetDir> [options]

Example:
  npx migrate-flat-routes ./app/routes ./app/flatroutes --convention=flat-folders

NOTE:
  sourceDir and targetDir are relative to project root

Options:
  --convention=<convention>
    The convention to use when migrating.
      flat-files - Migrates all files to a flat directory structure.
      flat-folders - Migrates all files to a flat directory structure, but
        creates folders for each route.

🔨 Flat Routes Convention

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

As React Router routes:

<Routes>
  <Route element={<Auth />}>
    <Route path="forgot-password" element={<Forgot />} />
    <Route path="login" element={<Login />} />
    <Route path="reset-password" element={<Reset />} />
    <Route path="signup" element={<Signup />} />
  </Route>
  <Route element={<Landing />}>
    <Route path="about" element={<About />} />
    <Route index element={<Index />} />
  </Route>
  <Route path="app" element={<App />}>
    <Route path="calendar" element={<Calendar />}>
      <Route path=":day" element={<Day />} />
      <Route index element={<CalendarIndex />} />
    </Route>
    <Route path="projects" element={<Projects />}>
      <Route path=":id" element={<Project />} />
    </Route>
  </Route>
  <Route path="app/projects/:id/roadmap" element={<Roadmap />} />
  <Route path="app/projects/:id/roadmap.pdf" />
</Routes>

Individual explanations:

filenameurlnests inside of...
_auth.forgot-password.tsx/forgot-password_auth.tsx
_auth.login.tsx/login_auth.tsx
_auth.reset-password.tsx/reset-password_auth.tsx
_auth.signup.tsx/signup_auth.tsx
_auth.tsxn/aroot.tsx
_landing.about.tsx/about_landing.tsx
_landing.index.tsx/_landing.tsx
_landing.tsxn/aroot.tsx
app.calendar.$day.tsx/app/calendar/:dayapp.calendar.tsx
app.calendar.index.tsx/app/calendarapp.calendar.tsx
app.projects.$id.tsx/app/projects/:idapp.projects.tsx
app.projects.tsx/app/projectsapp.tsx
app.tsx/approot.tsx
app_.projects.$id.roadmap.tsx/app/projects/:id/roadmaproot.tsx
app_.projects.$id.roadmap[.pdf].tsx/app/projects/:id/roadmap.pdfn/a (resource route)

Conventions

filenameconventionbehavior
privacy.jsxfilenamenormal route
pages.tos.jsxdot with no layoutnormal route, "." -> "/"
about.jsxfilename with childrenparent layout route
about.contact.jsxdotchild route of layout
about.index.jsxindex filenameindex route of layout
about_.company.jsxtrailing underscoreurl segment, no layout
_auth.jsxleading underscorelayout nesting, no url segment
_auth.login.jsxleading underscorechild of pathless layout route
users.$userId.jsxleading $URL param
docs.$.jsxbare $splat route
dashboard.route.jsxroute suffixoptional, ignored completely
_layout.jsxexplict layout fileoptional, same as parent folder
_route.jsxexplict route fileoptional, same as parent folder
investors/[index].jsxbracketsescapes conventional characters

Justification

  • Make it easier to see the routes your app has defined - just pop open "routes/" and they are all right there. Since file systems typically sort folders first, when you have dozens of routes it's hard to see which folders have layouts and which don't today. Now all related routes are sorted together.

  • Decrease refactor/redesign friction - while code editors are pretty good at fixing up imports when you move files around, and Remix has the "~" import alias, it's just generally easier to refactor a code base that doesn't have a bunch of nested folders. Remix will no longer force this.

    Additionally, when redesigning the user interface, it's simpler to adjust the names of files rather than creating/deleting folders and moving routes around to change the way they nest.

  • Help apps migrate to Remix - Existing apps typically don't have a nested route folder structure like today's conventions. Moving to Remix is arduous because you have to deal with all of the imports.

  • Colocation - while the example is exclusively files, they are really just "import paths". So you could make a folder for a route instead and the index file will be imported, allowing all of a route's modules to live along side each other.

For example, these routes:

routes/
  _landing.about.tsx
  _landing.index.tsx
  _landing.tsx
  app.projects.tsx
  app.tsx
  app_.projects.$id.roadmap.tsx

Could be folders holding their own modules inside:

routes/
  _auth/
    _layout.tsx <- explicit layout file (same as _auth.tsx)
  _auth.forgot-password/
    _route.tsx  <- explicit route file (same as _auth.forgot-password.tsx)
  _auth.login/
    index.tsx   <- route files (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/
    _layout.tsx <- explicit layout file (sames as app.projects.tsx)
    project-card.tsx
    get-projects.server.tsx
    project-buttons.tsx
  app.projects.$id/
    _route.tsx  <- explicit route file (sames as app.projects.$id.tsx)

This is a bit more opinionated, but I think it's ultimately what most developers would prefer. Each route becomes its own "mini app" with all of it's dependencies together. With the routeIgnorePatterns option it's completely unclear which files are routes and which aren't.

😍 Contributors

Thanks goes to these wonderful people (emoji key):


Kiliman

💻 📖

Ryan Florence

📖

Brandon Pittman

📖 💻

This project follows the all-contributors specification. Contributions of any kind welcome!

Keywords

FAQs

Package last updated on 27 May 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc