Electron Router DOM is here!
Tags: electron, react, javascript, typescript
Published: 2022-09-20 15:17:22

If you've already tried using react-router-dom with Electron, had difficulties getting it to work both in development and in production and in different windows, this library is for you 🚀

## Features
- 🚀 Ready for Development and Production environments
- 🔥 Works on Multiple windows
- 📦 Isolated routes by window id

## Installation
In your terminal, run:
```bash
yarn add electron-router-dom

# OR

npm i electron-router-dom
```
**Router DOM is a peer dependency**, if you haven't installed it yet or your package manager won't handle it automatically for you, so run:
```bash
yarn add react-router-dom

# OR

npm i react-router-dom
```

## Usage

The main thing to keep in mind is: you must **use the same window id** in the **Electron Main Process** used in `createFileRoute` and `createURLRoute` functions and in the **Electron Renderer Process** in the `<Router>` component prop names.

### Electron Main Process

```ts
import {
  app,
  BrowserWindow,
  BrowserWindowConstructorOptions as WindowOptions,
} from 'electron'

import { createFileRoute, createURLRoute } from 'electron-router-dom'
import { join } from 'path'

function createWindow(id: string, options: WindowOptions = {}) {
  const window = new BrowserWindow({
    width: 700,
    height: 473,
    ...options,
  })

  const devServerURL = createURLRoute(process.env['ELECTRON_RENDERER_URL']!, id)

  const fileRoute = createFileRoute(
    join(__dirname, '../renderer/index.html'),
    id
  )

  process.env.NODE_ENV === 'development'
    ? window.loadURL(devServerURL)
    : window.loadFile(...fileRoute)

  return window
}

app.whenReady().then(() => {
  createWindow('main', {
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
    },
  })

  createWindow('about', {
    width: 450,
    height: 350,
    show: false,
  })
})
```

### Electron Renderer Process

Create a `routes.tsx` file:
```tsx
import { Router, Route } from 'electron-router-dom'

import { MainScreen, AboutScreen, SearchScreen } from './screens'

export function AppRoutes() {
  return (
    <Router
      main={
        <>
          <Route path="/" element={<MainScreen />} />
          <Route path="/search" element={<SearchScreen />} />
        </>
      }
      about={<Route path="/" element={<AboutScreen />} />}
    />
  )
}
```
Then, import the `AppRoutes` in your `index.tsx`:
```tsx
import ReactDom from 'react-dom/client'
import React from 'react'

import { AppRoutes } from './routes'

ReactDom
  .createRoot(document.querySelector('app') as HTMLElement)
  .render(
    <React.StrictMode>
      <AppRoutes />
    </React.StrictMode>
  )
```
A simple example of a MainScreen component:
```tsx
import { useNavigate } from 'react-router-dom'

// The "App" comes from the context bridge in preload/index.ts
const { App } = window

export function MainScreen() {
  const navigate = useNavigate()

  return (
    <main>
      <button onClick={() => navigate('/search')}>Go to Search screen</button>

      <button onClick={App.OpenAboutWindow}>Open About window</button>
    </main>
  )
}
```

To get more knowledge about this library, please,
check the [Electron Router DOM GitHub Repository](https://github.com/daltonmenezes/electron-router-dom)

Thanks 💜