Pular para o conteúdo principal

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|1boolean
  • Country filtering: selectByCountry com 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

ArquivoPapel
app/services/brand.server.tsloadBrandConfig() — server-side
app/services/api.server.tsApiClient SSR (sem token)
app/routes/_layout.tsxLoader que chama brand + monta clientEnv
app/context/brand.tsxBrandProvider + useBrand()
app/context/env.tsxEnvProvider + useClientEnv()
app/layouts/DefaultLayout.tsxWraps providers