# Application

## new Application(options)

Creates an instance of a NocoBase application.

- Type

```tsx | pure
export interface ApplicationOptions {
  apiClient?: APIClientOptions | APIClient;
  ws?: WebSocketClientOptions | boolean;
  i18n?: i18next;
  providers?: (ComponentType | ComponentAndProps)[];
  plugins?: PluginType[];
  components?: Record<string, ComponentType>;
  scopes?: Record<string, any>;
  router?: RouterOptions;
  schemaSettings?: SchemaSetting[];
  schemaInitializers?: SchemaInitializer[];
  loadRemotePlugins?: boolean;
  dataSourceManager?: DataSourceManagerOptions;
  addFieldInterfaceComponentOption(fieldName: string, componentOption: CollectionFieldInterfaceComponentOption): void;
}
```

## Details
- `apiClient`: API request instance. For more details, refer to: [NocoBase API SDK Documentation](https://docs.nocobase.com/api/sdk)
- `i18n`: Internationalization. For specifics, see: [i18next API Documentation](https://www.i18next.com/overview/api#createinstance)
- `providers`: Context providers
- `components`: Global components
- `scopes`: Global scopes
- `router`: Route configuration. Refer to: [RouterManager](/core/application/router-manager)
- `pluginSettings`: [PluginSettingsManager](/core/application/plugin-settings-manager)
- `schemaSettings`: Schema settings tool. For more information, refer to: [SchemaSettingsManager](/core/ui-schema/schema-initializer-manager)
- `schemaInitializers`: Schema addition tool. For more information, refer to: [SchemaInitializerManager](/core/ui-schema/schema-initializer-manager)
- `loadRemotePlugins`: Used to control whether to load remote plugins. Default is `false`, meaning remote plugins are not loaded (convenient for unit testing and DEMO environments).
- `dataSourceManager`: Data source manager. For more details, refer to: [DataSourceManager](/core/data-source/data-source-manager)
- `addFieldInterfaceComponentOption`: Add field interface component options. For more details, refer to: [CollectionFieldInterfaceManager](/core/data-source/collection-field-interface-manager#addfieldinterfacecomponentoption)

## Example

```tsx
/**
 * defaultShowCode: true
 */
import { Application, Plugin } from '@nocobase/client';

const ProviderDemo = ({ children }) => {
    return <div>
        <div>hello world</div>
        <div style={{ marginTop: 10 }}>{children}</div>
    </div>
}

class MyPlugin extends Plugin {
    async load(){
        this.app.router.add('home', {
            path: '/',
            Component: () => <div>home page</div>
        })
    }
}

const app = new Application({
    providers: [ProviderDemo],
    plugins: [MyPlugin],
    router: {
        type: 'memory',
        initialEntries: ['/'],
    }
});

export default app.getRootComponent();
```

## Instance Properties

### app.i18n

```tsx | pure
class Application {
    i18n: i18next;
}
```

For a detailed introduction, please refer to: [i18next](https://www.i18next.com/overview/api#createinstance)

### app.apiClient

```tsx | pure
class Application {
    apiClient: APIClient;
}
```

For a detailed introduction, please refer to: [APIClient](https://docs.nocobase.com/api/sdk)

### app.router

For a detailed introduction, please refer to: [RouterManager](/core/application/router-manager)

### app.pluginSettingsManager

For a detailed introduction, please refer to: [PluginSettingsManager](/core/application/plugin-settings-manager)

### app.schemaSettingsManager

For a detailed introduction, please refer to: [SchemaSettingsManager](/core/ui-schema/schema-initializer-manager)

### app.schemaInitializerManager

For a detailed introduction, please refer to: [SchemaInitializerManager](/core/ui-schema/schema-initializer-manager)

### app.dataSourceManager

For a detailed introduction, please refer to: [dataSourceManager](/core/data-source/data-source-manager)

## Instance Methods

### app.getRootComponent()

Get the root component of the application.

- Type

```tsx | pure
class Application {
    getRootComponent(): React.FC
}
```

- Example

```tsx | pure
import { Application } from '@nocobase/client';

const app = new Application();

const App = app.getRootComponent();
```

### app.mount()

Mount the application instance in a container element.

- Type

```tsx | pure
class Application {
    mount(containerOrSelector: Element | ShadowRoot | string): ReactDOM.Root
}
```

- Example

```tsx | pure
import { Application } from '@nocobase/client';

const app = new Application();

app.mount('#root');
```

### app.addProvider()

Add `Provider` context.

- Type

```tsx | pure
class Application {
    addProvider<T = any>(component: ComponentType, props?: T): void;
}
```

- Details

The first parameter is the component, and the second parameter is the component's props. Note that the `Provider` must render its `children`.

- Example

```tsx | pure
// Scenario 1: Third-party library or self-created Context
const MyContext = createContext({});
app.addProvider(MyContext.provider, { value: { color: 'red' } });
```

```tsx
import { createContext, useContext } from 'react';
import { Application, Plugin } from '@nocobase/client';

const MyContext = createContext();

const HomePage = () => {
    const { color } = useContext(MyContext) || {};
    return <div style={{ color }}>home page</div>
}

class MyPlugin extends Plugin {
    async load(){
        this.app.addProvider(MyContext.Provider, { value: { color: 'red' } });
        this.app.router.add('home', {
            path: '/',
            Component: HomePage
        })
    }
}

const app = new Application({
    plugins: [MyPlugin],
    router: {
        type: 'memory',
        initialEntries: ['/'],
    }
});

export default app.getRootComponent();
```

```tsx | pure
// Scenario 2: Custom component, pay attention to children
const GlobalDemo = ({ name, children }) => {
    return <div>
        <div>hello, { name }</div>
        <div>{ children }</div>
    </div>
}
app.addProvider(GlobalDemo, { name: 'nocobase' });
```


```tsx
import { Application, Plugin } from '@nocobase/client';

const GlobalDemo = ({ name, children }) => {
    return <div>
        <div>hello, { name }</div>
        <div>{ children }</div>
    </div>
}

class MyPlugin extends Plugin {
    async load(){
        this.app.addProvider(GlobalDemo, { name: 'nocobase' });
        this.app.router.add('home', {
            path: '/',
            Component: () => <div>home page</div>
        })
    }
}

const app = new Application({
    plugins: [MyPlugin],
    router: {
        type: 'memory',
        initialEntries: ['/'],
    }
});

export default app.getRootComponent();
```


### app.addProviders()

Add multiple `Provider` contexts.

- Type

```tsx | pure
class Application {
    addProviders(providers: (ComponentType | [ComponentType, any])[]): void;
}
```

- Details

Add multiple `Provider` contexts at once.

- Example

```tsx | pure
app.addProviders([[MyContext.provider, { value: { color: 'red' } }], [GlobalDemo, { name: 'nocobase' }]])
```

### app.addComponents()

Add global components.

Global components can be used in [RouterManager](/core/application/router-manager) and [UI Schema](/core/ui-schema/schema-component).

- Type

```tsx | pure
class Application {
    addComponents(components: Record<string, ComponentType>): void;
}
```

- Example

```tsx | pure
app.addComponents({ Demo, Foo, Bar })
```

### app.addScopes()

Add global scopes.

Global scopes can be used in [UI Schema](/core/ui-schema/schema-component).

- Type

```tsx | pure
class Application {
    addScopes(scopes: Record<string, any>): void;
}
```

- Example

```tsx | pure
function useSomeThing() {}
const anyVar = '';

app.addScopes({ useSomeThing, anyVar })
```

### app.getCollectionManager()

Get the [collection manager](/core/data-source/collection-manager) instance of the specified data source.

- Type

```tsx | pure
class Application {
  getCollectionManager(dataSource?: string): CollectionManager;
}
```

- Example

```tsx | pure
app.getCollectionManager() // Get the default data source collection manager
app.getCollectionManager('test') // Get the specified data source collection manager
```

### app.addFieldInterfaceComponentOption()

Add field interface component option.

For a detailed introduction, please refer to: [CollectionFieldInterfaceManager](/core/data-source/collection-field-interface-manager#addfieldinterfacecomponentoption)

```tsx | pure
class MyPlugin extends Plugin {
  async load() {
    this.app.addFieldInterfaceComponentOption('url', {
      label: 'Preview',
      value: 'Input.Preview',
    });
  }
}
```

## Hooks

### useApp()

Get the instance of the current application.

- Type

```tsx | pure
const useApp: () => Application
```

- Example

```tsx | pure
const Demo = () => {
    const app = useApp();
    return <div>{ JSON.stringify(app.router.getRouters()) }</div>
}
```

```tsx
import { Application, Plugin, useApp } from '@nocobase/client';

const HomePage = () => {
    const app = useApp();
    return <div>{ JSON.stringify(app.router.getRoutes()) }</div>
}

class MyPlugin extends Plugin {
    async load(){
        this.app.router.add('home', {
            path: '/',
            Component: HomePage
        })
    }
}

const app = new Application({
    plugins: [MyPlugin],
    router: {
        type: 'memory',
        initialEntries: ['/'],
    }
});

export default app.getRootComponent();
```
