Plugin API
appDirectory
- Type:
string
- Default:
'app'
Remix use app
as the default directory for the routes, this plugin also use app
as the default directory for the routes. If you want to change the directory name, you can set the appDirectory
option.
import { defineConfig } from 'vite'
import { remixFlatRoutes } from 'vite-plugin-remix-flat-routes'
export default defineConfig({
plugins: [remixFlatRoutes({ appDirectory: 'src' })],
})
flatRoutesOptions
- Type:
Pick< FlatRoutesOptions, 'paramPrefixChar' | 'routeDir' | 'routeRegex' | 'visitFiles' | 'basePath' | 'ignoredRouteFiles' | 'defineRoutes'>
flatRoutesOptions
is same as remix-flat-routes
options, you can pass the options to the plugin.
Learn more about the options in the remix-flat-routes documentation
import { defineConfig } from 'vite'
import { remixFlatRoutes } from 'vite-plugin-remix-flat-routes'
export default defineConfig({
plugins: [
remixFlatRoutes({
flatRoutesOptions: {
ignoredRouteFiles: ['**/components/**'],
// other options
},
}),
],
})
routes
- Type:
( defineRoutes: DefineRoutesFunction, options: { ignoredRouteFiles: string[] }, ) => ReturnType<DefineRoutesFunction> | Promise<ReturnType<DefineRoutesFunction>>
You can define your own route convention by passing the routes
option to the plugin.
import { defineConfig } from 'vite'
import { remixFlatRoutes } from 'vite-plugin-remix-flat-routes'
export default defineConfig({
plugins: [
remixFlatRoutes({
routes(defineRoutes) {
return defineRoutes((route) => {
route('/somewhere/cool/*', 'catchall.tsx')
})
},
}),
],
})
legacy
- Type:
boolean
This plugin also support non data-api route, you can set the legacy
option to true
to enable the legacy route.
Plugin will detect react-router-dom package version to decide the route type in default. If the version is less than or equal to 6.3, the plugin will use the legacy route.
handleAsync
- Type:
boolean
- Default:
false
When the route is lazy-loaded but you want to pre-fetch the handle data, you can set handleAsync
to true
. The plugin will convert the handle
object into an asynchronous function, and you can manually execute the function to get the handle
data.
TIP
In legacy
routing mode, this option is always true
.
import { defineConfig } from 'vite'
import { remixFlatRoutes } from 'vite-plugin-remix-flat-routes'
export default defineConfig({
plugins: [
remixFlatRoutes({
handleAsync: true,
}),
],
})
For example, define a handle
object in the route file:
export const handle = {
prefetch: 'content',
}
Then handle the async handle in the outer route file:
// root.tsx
import { type LoaderFunction, matchRoutes, type RouteObject } from 'react-router-dom'
import { routes } from 'virtual:remix-flat-routes'
export const loader: LoaderFunction = async ({ request }) => {
await Promise.all(
matchRoutes(routes as RouteObject[], request.url)?.map(async (route) => {
const { handle } = route.route
if (typeof handle === 'function') {
// Execute the handle function to get data before the route loads
return await handle()
}
}) || [],
)
}
In addition to enabling the handleAsync
option, you can also use the dataStrategy
of react-router
to handle preloading logic uniformly, which is our recommended approach.
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
function App() {
return (
<RouterProvider
router={createBrowserRouter(routes, {
dataStrategy: async ({ matches }) => {
const matchesToLoad = matches.filter((m) => m.shouldLoad)
const results = await Promise.all(
matchesToLoad.map(async (match) => {
const result = await match.resolve()
const handle = match.route.handle
// You can get the handle data here
console.log(handle, 'handle')
return result
}),
)
return results.reduce(
(acc, result, i) =>
Object.assign(acc, {
[matchesToLoad[i].route.id]: result,
}),
{},
)
},
})}
/>
)
}
reactRefresh
- Type:
boolean
- Default:
true
@vitejs/plugin-react
hmr only support React components. Enable this option to hack the hmr to support react router data api
You should install @vitejs/plugin-react>=4.3.2
or @vitejs/plugin-react-swc>=3.6.0
If you have installed a plugin that meets the above conditions, we will automatically detect and enable the reactRefresh
option.