This page has not been translated into Spanish yet. The French version is shown.

Astuces

Cette page regroupe des astuces et bonnes pratiques pour le développement avec SmartMaker.

Utiliser la configuration

SmartCommon utilise LibConfigProvider pour centraliser la configuration de l'application.

// src/appConfig.js

export const appConfig = {
  debug: true, // Active les logs de debug
  api: {
    prefixUrl: import.meta.env.VITE_API_URL,
    timeout: 30000,
    debug: true
  }
};
// src/App.jsx

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

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

Pour accéder à la configuration dans un composant :

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

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

Composant Head

Pour modifier le titre et les meta de la page, utilisez react-helmet :

import { Helmet } from 'react-helmet';

export const MyPage = () => {
  return (
    <>
      <Helmet>
        <title>Ma Page - Mon App</title>
        <meta name="description" content="Description de ma page" />
      </Helmet>
      {/* Contenu de la page */}
    </>
  );
};

Composant Toaster

SmartCommon intègre react-hot-toast pour les notifications.

import toast from 'react-hot-toast';

// Notification de succès
toast.success('Enregistré avec succès !');

// Notification d'erreur
toast.error('Une erreur est survenue');

// Notification personnalisée
toast('Message neutre', {
  icon: '👋',
  duration: 4000,
});

// Notification avec promesse
toast.promise(
  saveData(),
  {
    loading: 'Enregistrement...',
    success: 'Données enregistrées',
    error: 'Échec de l\'enregistrement',
  }
);

Le Toaster est automatiquement inclus dans le Provider de SmartCommon.

Utiliser les variables d'environnement

Dans un environnement Vite, les variables d'environnement doivent être préfixées de VITE_.

# .env

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

On peut ainsi les importer avec import.meta.env :

// 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

Ne jamais commiter le fichier .env. Utilisez .env.example comme modèle.

Fichiers de traductions publiques

Les fichiers de traduction peuvent être chargés dynamiquement depuis le dossier public :

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

Configuration i18next :

// 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 };

Faire des fichiers de traductions "namespace"

Pour organiser les traductions par fonctionnalité :

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

Configuration :

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

Utilisation :

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

Utiliser des préfixes avec useTranslation

Pour éviter de répéter le chemin des clés :

// Sans préfixe
const { t } = useTranslation();
t('loginPage.form.emailInput.label');
t('loginPage.form.emailInput.placeholder');
t('loginPage.form.passwordInput.label');

// Avec préfixe
const { t } = useTranslation('translation', { keyPrefix: 'loginPage.form' });
t('emailInput.label');
t('emailInput.placeholder');
t('passwordInput.label');

Fichiers CSS publiques

Les fichiers CSS dans public/ ne sont pas traités par Vite et sont servis tels quels :

public/
  css/
    custom-theme.css

Pour les charger dynamiquement :

// Charger un thème CSS au runtime
const loadTheme = (themeName) => {
  const link = document.createElement('link');
  link.rel = 'stylesheet';
  link.href = `/css/${themeName}.css`;
  document.head.appendChild(link);
};

Retirer Tailwind CSS

Si vous ne souhaitez pas utiliser Tailwind CSS :

  1. Supprimer les dépendances :
npm uninstall tailwindcss @tailwindcss/vite
  1. Modifier vite.config.js :
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// Retirer: import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [
    react(),
    // Retirer: tailwindcss(),
  ]
});
  1. Supprimer les imports Tailwind dans vos fichiers CSS :
/* Retirer: @import "tailwindcss"; */

Importer les fichiers CSS entre eux

Avec Tailwind CSS 4

/* 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);

En CSS classique

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

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

Faire un listener de changement de thème

Pour détecter et réagir aux changements de thème (clair/sombre) :

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;
};

Utilisation :

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

  return (
    <div className={isDarkMode ? 'dark-theme' : 'light-theme'}>
      Mode actuel : {isDarkMode ? 'Sombre' : 'Clair'}
    </div>
  );
};

Pour changer le thème manuellement avec useGlobalStates :

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}>
      Passer en mode {theme === 'light' ? 'sombre' : 'clair'}
    </button>
  );
};

Voir aussi