Brand Loading (Server-Side)
Visão geral
A configuração de marca (brand) é carregada no server-side via React Router loader e passada aos componentes via Context.
Fluxo de dados
_layout.tsx loader (server-side)
├── createClient(cloudflareEnv) → ApiClient (sem token)
├── createBrandFromClient(client, { country, language }) → BrandConfig
│ ├── GET /appearance → transformAppearance
│ ├── GET /bff/features → transformFeatures
│ └── POST /bookmaker-settings → transformSettings
├── Monta clientEnv { API_BASE_URL, ORIGIN_DOMAIN, ... }
└── return { brand, clientEnv }
DefaultLayout (client-side)
├── <EnvProvider env={clientEnv}>
│ └── <BrandProvider brand={brand}>
│ └── useBrand() disponível em qualquer componente filho
Três requests em paralelo
O @cactus-agents/brand faz 3 requests simultâneos:
GET /appearance
Retorna dados visuais: logo, banners, social links, sponsorships, CSS customizado, cores do tema.
GET /bff/features
Feature flags por país: social auth, carousels, maintenance mode, auth config, módulos ativos, validação, contatos.
POST /bookmaker-settings
Configurações de negócio: nome, SEO, limites de depósito/saque/apostas, bônus, rollover, registro, analytics.
Transformações
O @cactus-agents/brand transforma os dados raw da API em tipos limpos:
- Banners:
{"1":{...}}objects OU[]→Banner[]sorted by order - Links: dedup (último LINK_TO_X entry vence)
- JSON string fields: parsed via
safeParseJson - Flags
0|1→boolean - Country filtering:
selectByCountrycom fallback chain
BrandConfig resultante
type BrandConfig = {
appearance: BrandAppearance // logo, banners, social, links, sponsorships, colors
features: BrandFeatures // feature flags, auth config, modules, contacts
settings: BrandSettings // name, SEO, limits, bonus, registration, analytics
}
Acesso nos componentes
import { useBrand } from '~/context/brand';
function MyComponent() {
const brand = useBrand();
// brand.appearance.logo
// brand.features.maintenanceMode
// brand.settings.name
}
Env vars de contexto
O loader também monta clientEnv com variáveis necessárias no client-side:
const clientEnv = {
API_BASE_URL: env.API_BASE_URL,
ORIGIN_DOMAIN: env.ORIGIN_DOMAIN,
BRAND_LANGUAGE: env.BRAND_LANGUAGE,
BRAND_COUNTRY: env.BRAND_COUNTRY,
BRAND_CURRENCY: env.BRAND_CURRENCY,
BRAND_TIMEZONE: env.BRAND_TIMEZONE,
};
Acessível via useClientEnv() de app/context/env.tsx.
Arquivos relevantes
| Arquivo | Papel |
|---|---|
app/services/brand.server.ts | loadBrandConfig() — server-side |
app/services/api.server.ts | ApiClient SSR (sem token) |
app/routes/_layout.tsx | Loader que chama brand + monta clientEnv |
app/context/brand.tsx | BrandProvider + useBrand() |
app/context/env.tsx | EnvProvider + useClientEnv() |
app/layouts/DefaultLayout.tsx | Wraps providers |