import { Meta } from '@storybook/addon-docs/blocks';

<Meta
    title="Get started/Installation: Client-side app"
    summary="How to install and set up Preply Design System in a client-rendered React application."
/>

# Installation: Client-side app

This guide sets up Preply Design System in a client-rendered React application.

If your application renders on the server, follow
[Installation: Next.js](/docs/get-started-installation-next-js--docs) instead.

See the complete [Vite example project](https://github.com/preply/design-system/tree/main/examples/vite).

## 1. Install the packages

Install the component packages, their peer dependencies, and the Design System translations:

```bash
npm install --save \
    @preply/ds-core \
    @preply/ds-core-types \
    @preply/ds-i18n \
    @preply/ds-media-icons \
    @preply/ds-theme-tokyo-ui \
    @preply/ds-visual-coverage-preply-component-names \
    @preply/ds-web-core \
    @preply/ds-web-lib \
    @preply/ds-web-root \
    react-intl@^6.5.5
```

Keep all `@preply/ds-*` packages on the same version, mixing versions can lead to unexpected behavior.

## 2. Load the global styles

Add the Design System stylesheet near the start of your application's `<head>`:

```html
<link rel="preconnect" href="https://static.preply.com" />
<link rel="stylesheet" href="https://static.preply.com/ds/global.css" />
```

The stylesheet supplies the global font declarations and base styles expected by Design System
components.

Add `data-preply-ds-theme="tokyo-ui"` to the element that contains your application. Global typography styles are scoped using this attribute:

```html
<div id="root" data-preply-ds-theme="tokyo-ui"></div>
```

## 3. Configure SVG imports

Design System icons are distributed as SVG files and must be transformed into React components.
Your bundler must load `.svg` files as React components with a default export:

```tsx
import Icon from './icon.svg';

<Icon />;
```

For Vite, install SVGR:

```bash
npm install --save-dev vite-plugin-svgr
```

Then configure it in `vite.config.ts`:

```ts
// vite.config.ts
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import svgr from 'vite-plugin-svgr';

export default defineConfig({
    plugins: [
        react(),
        svgr({
            svgrOptions: {
                exportType: 'default',
            },
            include: '**/*.svg',
        }),
    ],
});
```

To make sure icons are correctly typed, add ambient type declarations for `.svg` files:

```ts
// src/svg.d.ts
declare module '*.svg' {
    import type { FC, SVGProps } from 'react';

    declare const Component: FC<SVGProps<SVGSVGElement>>;

    export default Component;
}
```

If you use another bundler, configure its SVG transformer with the same default React-component
export behavior.

## 4. Add translations and `RootProvider`

Design System components use `react-intl`. Import the messages for your application's locale from
`@preply/ds-i18n`, merge them with your application messages, and pass the result to
`IntlProvider`.

Wrap the application with `RootProvider`. Targeting `document.body` applies the theme and color
scheme classes to the whole page, including content rendered through portals.

```tsx
import messages from '@preply/ds-i18n/locales/en.json';
import { RootProvider } from '@preply/ds-web-root';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { IntlProvider } from 'react-intl';

import { App } from './App';

const appMessages = {
    // Add application messages here.
};

createRoot(document.getElementById('root')!).render(
    <StrictMode>
        <IntlProvider locale="en" messages={{ ...appMessages, ...messages }}>
            <RootProvider theme="tokyo-ui" target={document.body}>
                <App />
            </RootProvider>
        </IntlProvider>
    </StrictMode>,
);
```

Import the locale matching the value passed to `IntlProvider`, for example
`@preply/ds-i18n/locales/de.json` for `locale="de"`.

## 5. Add component-specific global providers

`RootProvider` installs the shared theme, color scheme, portal, and tooltip infrastructure. Some
components have an additional provider because they need an application-level host or shared
state.

For example, if the application uses `AlertBanner`, place `AlertBannerProvider` near the top of the
tree so its accessible alerts region appears before the main page content:

```tsx
import { AlertBannerProvider } from '@preply/ds-web-lib';

<RootProvider theme="tokyo-ui" target={document.body}>
    <AlertBannerProvider>
        <App />
    </AlertBannerProvider>
</RootProvider>;
```

Add such providers only for the components your application uses.
