---
sidebar_position: 1
---

# Entries

Through this chapter, you can learn about the entry convention in Modern.js and how to customize the entry.

## What is an Entry

**Entry is the starting module of a page.**

In the Modern.js project, each entry corresponds to an independent page, and also corresponds to a server route. By default, Modern.js will automatically determine the entry of the page based on the directory convention, and also supports customizing the entry through configuration items.

Many configuration items provided by Modern.js are divided by entry, such as page title, HTML template, page Meta information, whether to enable SSR/SSG, server-side routing rules, etc.

## Single Entry and Multiple Entries

The project initialized by Modern.js is single-entry (SPA), and the project structure is as follows:

```
.
├── src
│   └── routes
│       ├── index.css
│       ├── layout.tsx
│       └── page.tsx
├── package.json
├── modern.config.ts
└── tsconfig.json
```

Modern.js can easily switch from single entry to multiple entry. You can execute `pnpm run new` under the project to create entry through generator:

```bash
? Please select the operation you want: Create Element
? Please select the type of element to create: New "entry"
? Please fill in the entry name: new-entry
```

After execution, Modern.js will automatically generate a new entry directory, and you can see that the `src/` directory has the following structure:

```bash
.
├── myapp     # Original entry
│   └── routes
│       ├── index.css
│       ├── layout.tsx
│       └── page.tsx
└── new-entry  # New entry
    └── routes
        ├── index.css
        ├── layout.tsx
        └── page.tsx
```

The original code was moved to the directory with the same name as the `name` in the `package.json`, and a new directory was created.

After executing `pnpm run dev`, you can see that a `/new-entry` route has been added, and the migrated code route has not changed.

:::tip
Modern.js will use the entry with the same name as the `name` field in the package.json file as the main entry, the route of the main entry is `/`, and the route of other entries is `/{entryName}`.

For example, when `name` in package.json is `myapp`, `src/myapp` will be used as the main entry of the project.

:::

## Entry Type

Different entry types have different compile and run-time behaviors. When creating a project in Modern.js, developers can manually choose to create a project in **framework mode** or **build mode**. After the creation is complete, you can see that the project template files for different modes are different.

By default, Modern.js will scan the files under `src/` before starting the project, identify the entry, and generate the corresponding server-side route.

:::tip
You can change the entry directory to another directory through [source.entriesDir](/configure/app/source/entries-dir).

:::

Not all first-level directories under `src/` will become project entries, and the directory where the entry is located must meet one of the following four conditions:

1. Have a `routes/` directory
2. Has `App.[jt]sx?` file
3. Has `index.[jt]sx?` file
4. Has a `pages/` directory (Modern.js 1.0 compatible)

When the `src/` directory meets the entry characteristics, Modern.js will consider the current project as a single-entry application.

:::tip
In single-entry applications, the default entry is named `main`.

:::

When the project is not a single-entry application, Modern.js will further check the first-level directory under `src/`.

### Framework Mode Entry

Framework mode refers to the need to use the capabilities of the Modern.js framework, such as Router, SSR, integrated calls, etc. Under this kind of entry agreement, the entry defined by the developer is not the real Webpack compilation entry. Modern.js will generate an encapsulated entry when it starts, and the real entry can be found in `node_modules/.modern/{entryName}/index.js`.

#### Conventional Routing

If there is a `routes/` directory in the entry, Modern.js will scan the files under `routes/` at startup, and automatically generate client-side routes (react-router) based on file conventions. For example:

```bash
.
├── src
│   └── routes
│       ├── layout.tsx
│       └── page.tsx
```

For details, please refer to [routing](/guides/basic-features/routes#conventional-routing).

#### Self-controlled Routing

If there is an `App.[jt]sx?` file in the entry, the developer can freely set the client route in this file, or not set the client route.

```tsx
import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';

export default () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route index element={<div>index</div>} />
        <Route path="about" element={<div>about</div>} />
      </Routes>
    </BrowserRouter>
  );
};
```

For details, please refer to [routing](/guides/basic-features/routes#self-controlled-routing).

#### Custom Bootstrap

If there is an `index.[jt]sx` file in the entry, and when the file defaults to exporting functions, Modern.js will pass the default bootstrap function as an imported parameter, and replace the default bootstrap with the exported function, so that developers can customize Mounting components to DOM nodes, or adding custom behavior before mounting. E.g:

```tsx
export default (App: React.ComponentType, bootstrap: () => void) => {
  // do something before bootstrap...
  initSomething().then(() => {
    bootstrap();
  })
};
```

:::warning
Since the bootstrap function needs to be compatible with React17 and React18, you need to manually pass in ReactDOM parameters when calling the bootstrap function.

:::

The content of the file generated by Modern.js is as follows:

```js
import React from 'react';
import ReactDOM from 'react-dom/client';
import customBootstrap from '@_modern_js_src/index.tsx';
import App from '@_modern_js_src/App';
import { router, state } from '@modern-js/runtime/plugins';

const IS_BROWSER = typeof window !== 'undefined' && window.name !== 'nodejs';
const MOUNT_ID = 'root';

let AppWrapper = null;

function render() {
  AppWrapper = createApp({
    // plugin parameters for runtime...
  })(App);
  if (IS_BROWSER) {
    customBootstrap(AppWrapper);
  }
  return AppWrapper;
}

AppWrapper = render();

export default AppWrapper;
```

### Build Mode Entry

Build mode refers to the ability not to use any Modern.js runtime, and the developer defines the entry of the project Webpack completely by himself.

If `index.[jt]sx` exists in the entry and there is no default export function, then this file is the real Webpack entry file. This is similar to [Create React App](https://github.com/facebook/create-react-app), you need to mount components to DOM nodes, add hot update code, etc. For example:

```js title=src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
```

Modern.js **not recommended** new project to use this method, this method loses some capabilities of the framework, such as the `runtime` configuration in the **`modern.config.js` file will no longer take effect**. But this method will be very useful when the project is migrated from other frameworks to Modern.js, such as CRA, or webpack that is manually built by yourself.

## Specify Entry Using Configuration

Most existing projects are not built according to the directory convention of Modern.js. If you want to change to the directory structure agreed by Modern.js, there will be a certain migration cost.

In this case, instead of generating the entry using file conventions, you can manually configure the entry in `modern.config.[jt]s`.

```ts title="modern.config.ts"
export default defineConfig({
  source: {
    entries: {
      // Specify a new entry named entry_customize
      entry_customize: './src/home/test/index.ts',
    },
    // Disable default ingress scanning
    disableDefaultEntries: true,
  },
});
```

### Disable Default Entries

When using a custom entry, part of the project structure may happen to hit the directory convention of Modern.js, but in fact this part of the directory is not the real entry.

Modern.js provides `disableDefaultEntries` config to disable default entry scanning rules. When you need to customize the entry, you generally need to use `disableDefaultEntries` with `entries`. In this way, some existing projects can be quickly migrated without modifying the directory structure.

```ts title="modern.config.ts"
export default defineConfig({
  source: {
    disableDefaultEntries: true,
  },
});
```

:::tip
For detailed usage, please refer to [source.entries](/configure/app/source/entries) and [source.disableDefaultEntries](/configure/app/source/disable-default-entries).

:::
