---
source_hash: "88155a7a"
title: "Tips and Tricks"
weight: 70
---

# Tips and Tricks

This page collects tips and best practices for developing with SmartMaker.

## Using the Configuration

SmartCommon uses `LibConfigProvider` to centralize the application configuration.

```javascript
// src/appConfig.js

export const appConfig = {
  debug: true, // Enable debug logs
  api: {
    prefixUrl: import.meta.env.VITE_API_URL,
    timeout: 30000,
    debug: true
  }
};
```

```javascript
// src/App.jsx

import { Provider } from '@cap-rel/smartcommon';
import { appConfig } from './appConfig';

export const App = () => {
  return (
    <Provider config={appConfig}>
      {/* Your application */}
    </Provider>
  );
};
```

To access the configuration in a component:

```javascript
import { useLibConfig } from '@cap-rel/smartcommon';

const MyComponent = () => {
  const config = useLibConfig();
  console.log(config.debug); // true
};
```

## Head Component

To modify the page title and meta tags, use `react-helmet`:

```javascript
import { Helmet } from 'react-helmet';

export const MyPage = () => {
  return (
    <>
      <Helmet>
        <title>My Page - My App</title>
        <meta name="description" content="My page description" />
      </Helmet>
      {/* Page content */}
    </>
  );
};
```

## Toaster Component

SmartCommon integrates `react-hot-toast` for notifications.

```javascript
import toast from 'react-hot-toast';

// Success notification
toast.success('Saved successfully!');

// Error notification
toast.error('An error occurred');

// Custom notification
toast('Neutral message', {
  icon: '👋',
  duration: 4000,
});

// Notification with promise
toast.promise(
  saveData(),
  {
    loading: 'Saving...',
    success: 'Data saved',
    error: 'Save failed',
  }
);
```

The `Toaster` is automatically included in SmartCommon's `Provider`.

## Using Environment Variables

In a **Vite** environment, environment variables must be prefixed with `VITE_`.

```
# .env

VITE_API_URL=https://api.example.com
VITE_APP_VERSION=1.0.0
VITE_APP_NAME=My Application
```

They can then be imported with `import.meta.env`:

```javascript
// src/utils/constants/vite.js

export const API_URL     = import.meta.env.VITE_API_URL;
export const APP_VERSION = import.meta.env.VITE_APP_VERSION;
export const APP_NAME    = import.meta.env.VITE_APP_NAME;
```

> [!IMPORTANT]
> Never commit the `.env` file. Use `.env.example` as a template.

## Public Translation Files

Translation files can be dynamically loaded from the `public` folder:

```
public/
  locales/
    fr.json
    en.json
    es.json
```

i18next Configuration:

```javascript
// src/i18n/index.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import HttpBackend from 'i18next-http-backend';

i18n
  .use(HttpBackend)
  .use(initReactI18next)
  .init({
    fallbackLng: 'fr',
    backend: {
      loadPath: '/locales/{{lng}}.json',
    },
  });

export { i18n };
```

## Namespace Translation Files

To organize translations by feature:

```
public/
  locales/
    fr/
      common.json
      login.json
      dashboard.json
    en/
      common.json
      login.json
      dashboard.json
```

Configuration:

```javascript
i18n.init({
  ns: ['common', 'login', 'dashboard'],
  defaultNS: 'common',
  backend: {
    loadPath: '/locales/{{lng}}/{{ns}}.json',
  },
});
```

Usage:

```javascript
const { t } = useTranslation('login');
// or
const { t } = useTranslation(['login', 'common']);
```

## Using Prefixes with useTranslation

To avoid repeating key paths:

```javascript
// Without prefix
const { t } = useTranslation();
t('loginPage.form.emailInput.label');
t('loginPage.form.emailInput.placeholder');
t('loginPage.form.passwordInput.label');

// With prefix
const { t } = useTranslation('translation', { keyPrefix: 'loginPage.form' });
t('emailInput.label');
t('emailInput.placeholder');
t('passwordInput.label');
```

## Public CSS Files

CSS files in `public/` are not processed by Vite and are served as-is:

```
public/
  css/
    custom-theme.css
```

To load them dynamically:

```javascript
// Load a CSS theme at runtime
const loadTheme = (themeName) => {
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = `/css/${themeName}.css`;
  document.head.appendChild(link);
};
```

## Removing Tailwind CSS

If you do not want to use Tailwind CSS:

1. Remove dependencies:

```bash
npm uninstall tailwindcss @tailwindcss/vite
```

2. Modify `vite.config.js`:

```javascript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// Remove: import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [
    react(),
    // Remove: tailwindcss(),
  ]
});
```

3. Remove Tailwind imports from your CSS files:

```css
/* Remove: @import "tailwindcss"; */
```

## Importing CSS Files Between Each Other

### With Tailwind CSS 4

```css
/* src/assets/styles/style.css */

@import "tailwindcss";

@layer theme, base, components;

@import "./theme.css" layer(theme);
@import "./base.css" layer(base);
@import "./components.css" layer(components);
```

### With Classic CSS

```css
/* src/assets/styles/style.css */

@import "./variables.css";
@import "./base.css";
@import "./components.css";
```

## Creating a Theme Change Listener

To detect and react to theme changes (light/dark):

```javascript
import { useEffect, useState } from 'react';

export const useThemeDetector = () => {
  const [isDark, setIsDark] = useState(
    window.matchMedia('(prefers-color-scheme: dark)').matches
  );

  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

    const handleChange = (e) => {
      setIsDark(e.matches);
    };

    mediaQuery.addEventListener('change', handleChange);

    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  return isDark;
};
```

Usage:

```javascript
const MyComponent = () => {
  const isDarkMode = useThemeDetector();

  return (
    <div className={isDarkMode ? 'dark-theme' : 'light-theme'}>
      Current mode: {isDarkMode ? 'Dark' : 'Light'}
    </div>
  );
};
```

To manually change the theme with `useGlobalStates`:

```javascript
import { useGlobalStates } from '@cap-rel/smartcommon';

const ThemeSwitcher = () => {
  const gst = useGlobalStates();
  const theme = gst.get('settings.theme') || 'light';

  const toggleTheme = () => {
    gst.local.set('settings.theme', theme === 'light' ? 'dark' : 'light');
  };

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
  }, [theme]);

  return (
    <button onClick={toggleTheme}>
      Switch to {theme === 'light' ? 'dark' : 'light'} mode
    </button>
  );
};
```

## See Also
- [SmartCommon](/front/smartcommon) - Component List
- [Hooks](/front/hooks) - Hook Documentation
- [Themes](/front/themes) - Theme Customization
