# Product Updates
Source: https://docs.deco.cx/changelog/overview
New updates and improvements
## 🎉 Celebrating 1000 PRs on deco-cx/apps! 🎉
### Timeline of Significant Features
#### 2025
* PR #996: Enhanced Product Data Handling in Schema.org Transformation
* PR #992: Support for displaying videos on Shopify products
* PR #988: Implementation of VTEX promotion loader
* PR #986: Reviews ordering system improvements
#### 2024
* PR #976: Blog features - Related posts functionality
* PR #963: Added pickup holidays type
* PR #958: Introduction of OneDollarStats collector
* PR #947: Optimization of asset proxying
* PR #920: Shopify signUp action implementation
* PR #917: Wake integration - Partner token functionality
#### 2023
* PR #830: SAP Commerce App integration
* PR #751: Wake buyList query implementation
* PR #703: Linx Commerce integration improvements
* PR #671: Smarthint Integration
* PR #634: Verified reviews product aggregation
* PR #435: Mailchimp integration
### Key Features Added
#### Commerce Integrations
* VTEX Integration enhancements
* Shopify features expansion
* Wake Commerce implementation
* SAP Commerce integration
* Linx Commerce improvements
* Nuvemshop Integration
#### Analytics & Marketing
* OneDollarStats collector
* Mailchimp integration
* Google Sheets functionality
* Enhanced analytics tracking
* Improved SEO capabilities
#### Product Features
* Enhanced product data handling
* Video support for products
* Reviews and ratings system
* Product aggregation in verified reviews
* Improved product listing capabilities
#### User Experience
* Blog functionality
* Pickup scheduling system
* Partner token system
* Enhanced shipping calculations
* Improved cart management
### Notable Contributors
#### Top Contributors
* @guitavano
* @mcandeia
* @tlgimenes
* @matheusgr
* @vitoUwu
#### New Contributors in Recent Milestones
* @gabriel-kerchner
* @AlexWasHeree
* @aline-pereira
* @gsbenevides2
* @pedrobernardina
### Impact
The repository has grown significantly, with contributions spanning various aspects of e-commerce and web development. The additions have enhanced the platform's capabilities in:
* Commerce platform integrations
* Analytics and tracking
* Content management
* User experience
* Performance optimization
* Marketing tools
This milestone represents the collaborative effort of the community in building a robust and feature-rich platform for digital commerce.
## Form select now keeps the correct type
Some types, such as the product listing page properties type selection, are now **correctly selected**.
This issue was caused by three main problems:
* RJSF was unable to distinguish between properties that have multiple types (e.g., `[string, number]`).
* There was an issue with schemas generated from apps before version 0.64.21, where a property type such as `[]` (empty array) was not allowed.
* RJSF didn't correctly cache a root schema with `$id`, as it also needed to cache the same root schema with `ROOT_SCHEMA_PREFIX` as the id.
If you are still experiencing issues with this bug, please **update to the latest version of the app**.
## AI Input form fill
We added a tool for select input that uses contextual information to generate text.
Under the hood, we use the Sonnet 3.5 model to generate information, expanding the prompt by extracting context from the page itself.
An additional prompt can be used to improve the result of the task. A diff between the current input and the proposed AI input is shown before confirmation.
For each string property, you can use the `@aiContext` annotation to provide additional context for the user.
We aim to expand this utility across all our products and allow your own AI apps to edit and create data for your site!
## Webdrawm in admin
Introducing Webdraw! This new tool allows you to create AI-driven sections directly within our admin interface.
To create a section, use Webdraw and press `⌘ (CTRL) + P` to push your section to the admin and start using it.
You may need a tailored prompt to achieve the best results. For example, you can copy the code from an existing section as a reference.
We have made our default [deco prompt available here](https://gist.github.com/matheusgr/bbdcab6747cccb83e18254304d0970fc).
Please note that AI may sometimes generate invalid TSX code, so some manual adjustments might be necessary.
Note: This feature is still experimental!
# null
Source: https://docs.deco.cx/pt/api-reference/invoke
Invoke Client API Reference
A API Invoke é um cliente RPC (Remote Procedure Call) tipado. Ela torna a
interação com loaders e actions mais segura e tão fácil quanto chamar uma
função, abstraindo os detalhes do transporte de rede acontecendo por baixo dos
panos.
Um único cliente Invoke pode ser usado para interagir com ações e carregadores
do seu site e de qualquer App instalado. O Invoke pode ser usado tanto no
Cliente quanto no Servidor e suporta padrões mais complexos, como chamar
múltiplos loaders/actions em uma única requisição (Veja o Exemplo 4: Invoke em
Batch) ou enviar arquivos via uma requisição multipart.
A assinatura de tipo de Invoke será sempre dinâmica e será inferida com base no
tipo do seu manifesto e no tipo da ação/carregador que você está chamando:
Por exemplo:
```typescript
import { invoke } from "site/runtime.ts";
const resultado = await invoke.site.loaders.exemplo(
props: T, // Este será o tipo das props da action/loader sendo chamado
init?: InvokerRequestInit // Este é um objeto de inicialização de requisição fetch estendido com algumas opções extras
);
console.log(resultado); // Este será o tipo do valor de retorno da action/loader
```
## Importando a API
### Uso no Browser (client-side)
Para uso no Cliente, o Invoke é exportado da `runtime.ts` no raiz do projeto.
Abaixo está um exemplo de um arquivo `runtime.ts` típico, que cria um cliente
para interagir com actions e loaders do seu site, e de dois apps: VTEX e Linx
Impulse. Todos os Apps podem ser usados da mesma forma, já que exportam um
`Manifest`.
```typescript
import { proxy } from "deco/clients/withManifest.ts";
import type { Manifest } from "./manifest.gen.ts";
import type { Manifest as ManifestVTEX } from "apps/vtex/manifest.gen.ts";
import type { Manifest as ManifestLinxImpulse } from "apps/linx-impulse/manifest.gen.ts";
export const invoke = proxy();
```
### Uso no Servidor
Para uso no Servidor, o Invoke pode sempre ser acessado a partir do *Contexto*
da Aplicação. Isso torna o Invoke mais fácil de usar dentro de actions e
loaders.
Abaixo está um exemplo de um loader que utiliza o Invoke para chamar outro
loader da mesma Aplicação:
```typescript
import type { AppContext } from "site/apps/site.ts";
export const async function getUserNotes(
props: Props, req: Request, ctx: AppContext
): Promise {
const user = await ctx.invoke.site.loaders.getUser({ token: req.headers.get("Authorization") });
if (!user) {
throw new Error("Usuário não encontrado");
}
return user.notes;
}
```
## Exemplos de Uso
### Exemplo 1: Chamando uma Action ou Loader a partir do Navegador
Suponha que temos um loader chamado `getUser`, que retorna um objeto de usuário,
baseado em um `id` de usuário enviado.
```typescript
import type { AppContext } from "site/apps/site.ts";
export interface Props {
id: string;
}
export const async function getUser(
props: Props, req: Request, ctx: AppContext
): Promise {
return fetchUser(props.id);
}
```
Podemos agora chamar esse loader a partir do Navegador, usando o cliente invoke
exportado do arquivo runtime.ts:
```typescript
import { invoke } from "site/runtime.ts";
const user = await invoke.site.loaders.getUser({ id: "123" });
```
Como o cliente Invoke é tipado, o tipo de retorno do `getUser` é automaticamente
inferido, e o tipo da variável `user` é `User`. Todos os tipos de parâmetros são
também inferidos, então temos mais confiança para interagir com nossas APIs.
**Importante**: Isso deve ser usado apenas no Navegador. Tentar importar e usar
o cliente Invoke do arquivo `runtime.ts` no servidor resultará em um erro. Para
chamar actions/loaders a partir do servidor, veja o próximo exemplo.
### Exemplo 2: Chamando uma Action ou Loader a partir do Servidor
Suponha que estamos criando uma ação chamada `addItem` que adiciona um item a um
carrinho.
Suponha também que já temos um loader chamado `cart`, que retorna o carrinho
atual para um usuário, baseado em uma sessão contida nos cookies da requisição:
```typescript
import type { AppContext } from "site/apps/site.ts";
import { getSessionFromRequest } from "site/lib/session.ts";
import { getCartFromDatabase } from "site/lib/cart.ts";
export interface CartItem {
productId: string;
quantity: number;
}
export interface Cart {
items: CartItem[];
id: string;
}
export const async function cart(
_props: unknown, req: Request, ctx: AppContext
): Promise {
// Pegar a sessão a partir da requisição
const session = await getSessionFromRequest(req);
// Pegar o carrinho a partir da base de dados usando o ID vindo da sessão
const cart = await getCartFromDatabase(session.cartId);
return cart;
}
```
Agora, quando criamos a ação `addItem`, podemos reutilizar o loader `cart` para
buscar o carrinho atual e então adicionar o item ao carrinho:
```typescript
import type { AppContext } from "site/apps/site.ts";
import { saveCartToDatabase } from "site/lib/cart.ts";
export interface Props {
item: CartItem;
}
export const async function addItem(
props: Props, req: Request, ctx: AppContext
): Promise {
const currentCart = await ctx.invoke.site.loaders.cart();
// Adicionar o item ao carrinho
cart.items.push(props.item);
// Salvar o carrinho atualizado na base de dados
await saveCartToDatabase(cart);
return cart;
}
```
O cliente Invoke que vem do Contexto da Aplicação é também tipado, baseado no
tipo `AppContext` exportado por convenção do seu `site` app.
### Exemplo 3: Enviando um arquivo para o Servidor
Suponha que temos uma ação chamada `uploadFile`, que envia um arquivo para um
destino. A ação recebe uma propriedade `file`, que é um objeto de arquivo que
contém os dados do arquivo, e uma propriedade `destination`, que é uma string
que especifica o destino para onde o arquivo deve ser enviado.
```typescript
import type { AppContext } from "site/apps/site.ts";
export interface Props {
file: File;
destination: string;
}
export const async function uploadFile(
props: Props, req: Request, ctx: AppContext
): Promise {
// Enviar o arquivo para o destino
await uploadFileToDestination(props.file, props.destination);
}
```
Estamos usando a web API `File` como tipo de propriedade aqui, mas isso cria um
problema:
O objeto `File` não é serializável via JSON, que é o que o Invoke usa
internamente. Isso significa que tentar passar um objeto File como propriedade
para uma ação resultará em um erro ao tentar acessar a propriedade file dentro
da sua action.
Para resolver isso, o cliente Invoke oferece uma maneira de fazer upload de
arquivos via uma requisição multipart, que é uma maneira prática de enviar
arquivos para o servidor, usando a API FormData e o tipo de conteúdo
multipart/form-data.
Para usar isso, você só precisa adicionar uma opção multipart: true ao
`InvokerRequestInit` do Invoke (que é o segundo argumento para qualquer chamada
de invoke), e o cliente usará automaticamente um protocolo personalizado para
enviar o payload via multipart, tornando possível enviar arquivos para o
servidor.
Podemos agora chamar essa ação a partir do Navegador, usando o cliente invoke
exportado do arquivo runtime.ts:
```tsx
import { invoke } from "site/runtime.ts";
export function UploadFileInput() {
const uploadFile = async (file: File) => {
await invoke.site.actions.uploadFile({
file: file,
destination: "/uploads/files",
}, { multipart: true });
};
return (
{
const file = e.target.files[0];
if (file) {
await uploadFile(file);
}
}}
/>
);
}
```
Agora o arquivo `file` pode ser acessado seguramente na action!
**Importante**: Quando usando a opção `multipart`, o cliente Invoke enviará um
FormData objeto para o servidor, que só suporta arquivos e strings. Isso
significa que qualquer propriedade que seja um número ou um booleano será
convertida para uma string.
### Exemplo 4: Batch Invoke
Batch Invoke é útil quando você precisa realizar múltiplas operações
simultaneamente e quer minimizar a latência de rede, reduzindo o número de
requisições.
Aqui está um exemplo de cenário onde usar Batch Invoke faz sentido: recuperar
múltiplos conjuntos de dados relacionados em uma única requisição.
Suponha que temos um usuário logado e temos três diferentes loaders que retornam
dados relacionados ao usuário: um para anotações (notes), um para o endereço
(address) e um para os pedidos (orders).
Podemos recuperar todos esses três conjuntos de dados em uma única requisição
usando um Batch Invoke:
```typescript
import { invoke } from "site/runtime.ts";
// Podemos sempre desstructurar o cliente Invoke
// para escrever código mais fácil de ler
const { loaders } = invoke.site;
const user = ...; // Obtenha o usuário atual de alguma maneira
const {
userNotes,
userAddress,
userOrders,
} = await invoke({
userNotes: loaders.getUserNotes({ userId: user.id, orderBy: "latest" }),
userAddress: loaders.getUserAddress({ token: user.token }),
userOrders: loaders.getUserOrders({ userId: user.id }),
});
```
Passando um objeto com os loaders/actions como propriedades, o cliente Invoke
automaticamente faz o batch das requisições e retorna os resultados no mesmo
formato que o objeto passado. Continuamos tendo todos os tipos inferidos
automaticamente ao fazer Batch Invoke desta maneira!
# null
Source: https://docs.deco.cx/pt/api-reference/use-script
useScript API reference
### Descrição
A função `useScript` foi projetada para ajudar os desenvolvedores a inserir
scripts diretamente em uma página da web com uma carga mínima. Ela recebe uma
função e seus argumentos como parâmetros e retorna a versão convertida em string
e minificada da função. Isso é particularmente útil para inserir manipuladores
de eventos e outros scripts diretamente no HTML, otimizando o desempenho ao
reduzir a quantidade de JavaScript enviado pela rede. Ela se integra
perfeitamente com os manipuladores `hx-on:` do HTMX.
### Importação
```typescript
import { useScript } from "deco/hooks/useScript.ts";
```
### Parâmetros
* **fn**: `Function`
* A função a ser convertida em string e minificada.
* **args**: `...any[]`
* Os argumentos a serem passados para a função quando ela for chamada.
### Valor de Retorno
* **string**
* Uma versão convertida em string e minificada da função, pronta para ser
inserida no HTML.
### Exemplos de Uso
#### Exemplo 1: Script Inline com `dangerouslySetInnerHTML`
Neste exemplo, `useScript` é usado para inserir um script simples que registra
uma mensagem quando a janela é carregada.
```tsx
import { useScript } from "deco/hooks/useScript.ts";
const onLoad = () => {
console.log("Window loaded");
};
function ExampleComponent() {
return (
Hello, World!
);
}
export default ExampleComponent;
```
#### Exemplo 2: Script Inline com Atributo `hx-on`
Neste exemplo, `useScript` é usado para criar um manipulador de eventos
minificado para um atributo `hx-on:click` que altera o texto de um botão quando
clicado.
```tsx
import { useScript } from "deco/hooks/useScript.ts";
const onClick = () => {
event!.currentTarget.innerText = "Clicked!";
};
function ExampleButton() {
return (
);
}
export default ExampleButton;
```
### Notas
* Certifique-se de que a função passada para `useScript` não dependa de
variáveis externas ou closures que não estarão disponíveis quando o script for
executado inline.
* Ao usar com manipuladores `hx-on:`, certifique-se de que a função minificada
não exceda os limites de comprimento de atributos que podem ser impostos pelos
navegadores ou especificações HTML.
# null
Source: https://docs.deco.cx/pt/api-reference/use-section
useSection API reference
O hook `useSection` no deco.cx é uma ferramenta poderosa projetada para gerar
automaticamente links para atualização e renderização de seções. Com este hook,
você pode usar os Partials do HTMX ou Fresh para renderizar estados específicos
de seções. Abaixo está uma explicação detalhada de seu uso, parâmetros e
exemplos.
## Importando o Hook useSection
Para usar o hook useSection, você precisa importá-lo do arquivo
deco/hooks/useSection.ts:
```tsx
import { useSection } from "deco/hooks/useSection.ts";
```
## Parâmetros
O hook useSection aceita um objeto de opções com as seguintes propriedades:
1. **props**: Um objeto contendo as propriedades da seção a serem substituídas.
Isso permite que você especifique novos valores para as propriedades que
serão usadas para renderizar a seção. Lembre-se de que as propriedades são
mescladas com aquelas da instância atual da seção.
2. **href**: Uma string que representa a nova URL para avaliar esta seção. Esta
URL será usada para o parâmetro `Request` em todos os loaders/actions dos
quais esta seção pode depender.
## Valor de Retorno
O hook useSection retorna uma string de URL da seção com as propriedades
aplicadas parcialmente.
## Exemplo de Uso
Vamos construir um componente que imprime um número inteiro e nos permite ver o
próximo número inteiro. Aqui está uma ilustração:

Este componente pode ser construído com o seguinte código:
```tsx
import { useSection } from "deco/hooks/useSection.ts";
export default function Section({ count = 0 }: { count: number }) {
return (
);
}
```
Onde useSection retorna um link para o próximo número inteiro.
## Avisos
1. **Limites de Tamanho de URL**: Esteja atento aos limites de tamanho da URL ao
passar propriedades para useSection. Tente manter os payloads pequenos e use
tipos de dados leves, como booleanos e IDs.
2. **Segurança**: Garanta que quaisquer dados sensíveis passados como
propriedades estejam devidamente protegidos e não exponham vulnerabilidades
através da URL.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/actions
Actions (execução de ações)
As actions representam funções que tipicamente são invocadas pelos usuários no
browser. Por exemplo, se cadastrar em uma newsletter, adicionar um item a um
carrinho de compras ou qualquer operação que exija a intervenção de um servidor.
Na plataforma, você pode testar tais ações, ou mesmo ter actions que são apenas
executadas nessa interface administrativa.
Ao contrário de sections e loaders, é possível salvar entidades
pré-configuradas, mas não há muita utilidade nisto. Neste sentido, acessando a
barra lateral `Advanced > Actions`, você terá acesso a biblioteca de actions e a
possibilidade de criar, salver, editar e executar actions existentes.
As diferentes categorias presentes na listagem são obtidas a partir do diretório
que a action se encontra ou da **App** na qual ela origina (uma **App** pode
importar diferentes actions).
A partir desta tela é possível:
* **Saved**: Listar as actions salvas
* **Library**: Listar e testar todas as actions disponíveis para uso
* **Create new Action**: Criar novas actions
## Listar e testar actions
Ao listar as actions na library, e ao clicar em uma action, você passa a ter
acesso a uma visualização da Action, bem como acesso ao código original daquele
elemento. É também possível editar o código, para testar alterações na
funcionalidade do componente.
Na barra lateral a direita, é possível acessar:
* `🌐` Visuzalização do elemento
* `☰` Formulário com propriedades
* `{}` Descrição textual das propriedades
* `>` Editor de código
* `🖥️` Logs relacionados a visualização do loader
* `✨` Decopilot: IA para alteração do código
## Criar nova Action
É possível criar uma action salva ou a base (template) de uma action.
* **Create template**: Cria uma action que será disponibilizada na biblioteca de
componentes. Isto significa criar uma base de código que definirá um conjunto
de propriedades e um programa para retornar dados.
* **Using a template**: Cria uma action salva a partir de uma base existente. O
nome será a identificação deste elemento.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/apps
Instalando apps
# Pré-requisitos
Antes de começar, certifique-se de ter um site deco pronto, e a App desejado
deve estar disponível no diretório Apps. Se você não tem certeza de como fazer
isso, consulte o
[tutorial de tornar uma app instalável](https://deco.cx/docs/pt/developing/making-an-app-installable).
# Apps
Uma `App` permite adicionar novas funcionalidades no seu site de maneira bem
direta.
# Instalando a app
1. **Acesse o deco Admin:** Comece fazendo login na sua conta do
[deco Admin](https://admin.deco.cx).
2. **Escolha o Site de Destino:** Após fazer login, selecione o site específico
onde deseja instalar o App. Você será direcionado para a página inicial do
site.
3. **Acesse a Seção "Apps":** Na página inicial do site, navegue até a seção
"Apps". Esta é a seção onde você encontrará todos os Apps disponíveis para
instalação. Selecione para ver todos os Apps disponíveis.

4. **Adicione um Bloco da app:** Clique em adicionar App. Isto inicia o processo
de criar um bloco. Configure o bloco e clique em criar. (dê a ele um nome; é
comum usar a versão, como `site@v0`).
5. **Explore os Blocos Instalados:** Depois de instalado, você terá acesso a
todos os blocos e componentes que um App inclui. Esses blocos podem ser
integrados ao seu site deco para fornecer funcionalidades adicionais.
Parabéns! Você instalou com sucesso um App usando o deco Admin. Explore as novas
capacidades e recursos que um App instalado traz para o seu site deco. Sinta-se
à vontade para personalizar o App ainda mais ou explorar outros Apps disponíveis
para expandir as funcionalidades do seu projeto deco. Aproveite para gerenciar e
aprimorar o seu site deco! 🚀
> É possível sempre alterar as configurações do Apps clicando no bloco criado.

# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/experiments
Guia sobre experimentos.
Funcionalidade ainda em desenvolvimento.
Para saber mais, acesse a documentação sobre
[Teste A/B](https://deco.cx/docs/pt/developing-capabilities/apps/ab-test).
# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/loaders
Loaders (carregamento de dados)
Os loaders representam componentes que podem ser utilizados para carregar dados.
Especialmente, os loaders podem ser usados para preencher dados de propriedades
de sections. Se uma section espera receber um dado estruturado que representa um
produto, isto pode ser preenchido manualmente para uma página, mas pode ser
carregado através de um loader.
Loaders podem fazer uso do contexto da requisição que o usuário faz, por
exemplo, a URL que o usuário usou para acessar, sua localização, ou outros dados
para determinar o dado a ser carregado. Da mesma forma, os Loaders também podem
fazer uso das configuraçãoes de uma App que ele faz parte.
E, por fim, os próprios loaders podem ter propriedades que são definidas pelos
usuários que os usam.
Ao abrir os loaders (barra lateral `Advanced > Loaders`), você terá acesso a um
conjunto de loaders salvos, a biblioteca de loaders e a possibilidade de criar,
editar e salvar loaders.
As diferentes categorias presentes na listagem são obtidas a partir do diretório
que o loader se encontra ou da **App** na qual ele origina (uma **App** pode
importar diferentes loaders).
A partir desta tela é possível:
* **Saved**: Listar os loaders salvos
* **Library**: Listar e testar todos os loaders disponíveis para uso
* **Create new Loader**: Criar novos Loaders
## Alterar loaders salvos
Um **loader salvo** representa um loader que pode ser utilizado em diferentes
sections. Desta forma, um mesmo loader pode ter a mesma configuração a ser
aplicada em diferentes lugares do site. Ao mesmo tempo, isto permite que uma
única alteração ao loader salvo impacte várias partes do sistema.
> Caso uma página faça uso de um mesmo loader salvo em diferentes sections de
> uma página, este loader é carregado apenas uma vez. Isto torna o sistema
> extremamente eficiente! Por exemplo, um componente como `SearchResult` e
> `SEOPLP` podem precisar carregar os produtos de uma prateleira durante o
> carregamento de uma página. Caso ambas as sections que estejam nessa página
> façam uso de um mesmo loader salvo (ex.: `PLP Loader`), este será carregado
> apenas uma vez.
Ao clicar em um loader salvo é possível alterar suas propriedades configuradas
anteriormente.
Ao selecionar um loader, será possível definir suas propriedades. Algumas das
propriedades podem pedir a seleção de uma imagem, texto, seleção de itens, ou
mesmo outro **loader**!
É possível executar um loader para verificar quais dados são retornados durante
sua execução. Para tanto, é possível cirar no botão `Run`, que executará o
código associado a esse loader, e mostrará os dados de resposta.
## Listar e testar demais loaders
Ao listar os loaders na library, e clicar em um loader, você passa a ter acesso
a uma visualização do Loader, bem como acesso ao código original daquele
elemento. É também possível editar o código, para testar alterações na
funcionalidade do componente.
Na barra lateral a direita, é possível acessar:
* `🌐` Visuzalização do elemento
* `☰` Formulário com propriedades
* `{}` Descrição textual das propriedades
* `>` Editor de código
* `🖥️` Logs relacionados a visualização do loader
* `✨` Decopilot: IA para alteração do código
## Criar novo Loader
É possível criar um loader salvo (um componente compartilhável entre várias
sections ou blocos) ou a base (template) de um loader.
* **Create template**: Cria um loader que será disponibilizado na biblioteca de
componentes. Isto significa criar uma base de código que definirá um conjunto
de propriedades e um programa para retornar dados.
* **Using a template**: Cria um loader salvo a partir de uma base existente. O
nome será a identificação deste elemento.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/redirects
Aprenda como criar proxies e redirecionamentos para uma rota específica
Adicionar **proxies** e **redirecionamentos** são práticas comuns no
desenvolvimento web para *melhorar a experiência do usuário* e *otimizar a
entrega de conteúdo*. Proxies e redirecionamentos têm finalidades diferentes e
podem ser benéficos em diversos cenários.
Os **redirecionamentos** são principalmente utilizados quando você tem uma
página que pode *não existir mais*, mas que ainda é acessada pelos usuários
através de marcadores salvos ou links externos. Em vez de retornar um erro 404
(não encontrado), você pode criar um redirecionamento para garantir uma
transição tranquila para seus usuários. Ao implementar redirecionamentos, seu
site pode continuar servindo o conteúdo desejado para essas rotas específicas,
mantendo uma experiência positiva para o usuário.
Ao utilizar proxies e redirecionamentos, você pode otimizar a entrega de
conteúdo, gerenciar transições e fornecer uma experiência de usuário perfeita.
Nas seções a seguir, vamos explorar como adicionar proxies e redirecionamentos
usando o Admin da deco, passo a passo.
O processo geral envolve a alteração do mapa de rotas do site e a associação de
um proxy ou redirecionamento, dependendo do caso de uso específico. Ao final do
processo, saberemos como criar uma rota de exemplo `/example-proxy` que faz
proxy de solicitações para o deco.cx e uma rota `/example-redirect` que
redireciona para a página inicial do google.com. Observe a diferença: o primeiro
manterá você no mesmo domínio, enquanto o último o levará para fora do domínio
do seu site.
## Adicionando um redirect
### 1. Acessar a Página de Redirects
Acesse a página de `redirects`. Isto permite acesso a criação de redirects.
### 2. Pressione o Create a redirect
Faça a configuração do redirecionamento de acordo com sua necessidade:
* **From**: o campo de origem, que representa o caminho que o usuário está
tentando acessar, e na qual ele será redirecionado. Este campo suporta o
[URLPattern](http://mdn.io/urlpattern).
* **To**: o campo de destino. Pode ser um endereço absoluto ou um caminho
relativo
* **Type**: a definição do tipo de redirect (`permanent` ou `temporary`)
> Escolha o tipo como `temporary`, quando o redirecionamento pode mudar ao longo
> do tempo. Se o redirecionamento não deve mudar ao longo do tempo, você pode
> selecionar `permanent` (o que pode resultar em respostas mais rápidas, já que
> os redirecionamentos permanentes são armazenados em cache pelo navegador do
> usuário).
### 3. Crie o redirect
Para o redirect entrar em efeito, é preciso publicar as alterações do seu site.
Em seguida, você pode acessar `https://seu-site.deco.site/example-redirect` e
verificar se o redirecionamento está funcionando corretamente.
## Adicionando um Proxy \[via apps de ecommerce e website]
Proxies são utilizados quando você deseja *manter o usuário* dentro do *mesmo
site, mas fornecendo um conteúdo diferente*. Os **proxies** permitem o
compartilhamento de recursos sob o mesmo domínio, proporcionando uma experiência
de usuário unificada. Isso pode ser especialmente útil quando você precisa
servir conteúdo de diferentes fontes ou plataformas, mantendo uma interface de
usuário consistente. Os proxies são comumente usados durante processos de
migração de plataforma, permitindo que você adote gradualmente o Deco e decida
se uma página específica deve ser proxied ou servida diretamente pelo Deco.
Para criar ou editar um proxy em vez de um redirecionamento, você pode seguir os
seguintes passos:
### 1. Acesso o `App` de site
Acesse a visualização de apps do site, e procure pelo `App` de site. Para
editá-lo, clique na descrição do app.
### 2. Procure peloRoutes Map
Procure no formulário de edição do app, pela propriedade de routes map.
Edite o proxy existente para adicionar novas rotas a serem proxiadas (quando for
o caso) ou adicione um proxy obtido de algum app de e-commerce.
Publique as alterações para que a nova rota de proxy entre em efeito.
## Adicionando um arquivo de redirects.
Repita o passo 1 da seção anterior e procure pelo `Route Maps`.
Em seguida:
1. Suba um arquivo como `redirect.csv` para a base do projeto. Ele deve ter o
formato indicado abaixo:
```
from,to,type
/example-redirect,/test,temporary
/google,https://www.google.com,permanent
```
2. Adicione a rota do tipo `redirectsFromCsv.ts`.
3. Selecione `redirect.csv` como arquivo de redirects.
4. Publique as alterações.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/segments
Aprenda como criar variações de conteúdo com base em condições específicas
**Variantes** permitem segmentar o conteúdo com base em certas *condições*,
permitindo personalizar e adaptar as páginas para diferentes *segmentos* de
usuários. Por exemplo, você pode criar uma variante para alterar o layout da
página toda **sexta-feira** para **50% dos usuários**. Ao utilizar variantes,
você pode modificar dinamicamente o conteúdo direcionado a segmentos específicos
de sua audiência.
As **variantes** são impulsionadas por **Matchers** (ou **Segments**), que são
*blocos* usados para avaliar *condições* específicas com base em
*características do usuário*, *data e hora*, *seleção aleatória* (testes A/B),
*histórico de navegação do usuário*, *dispositivo do usuário*, ou *qualquer
informação externa extraída da solicitação*. **Matchers** são configurados para
determinar se um usuário pertence a um determinado **Segmento** ou não.
**Segmentos** se referem a uma parte dos usuários do seu site que satisfazem as
condições definidas pelos matchers. Um usuário pode pertencer a vários
**segmentos** simultaneamente. Por exemplo, um usuário pode fazer parte do
segmento `São Paulo`, que segmenta usuários localizados em `São Paulo`, e também
pode fazer parte de um experimento que inclui 50% dos usuários. **Segmentos**
podem ser combinados para criar critérios de segmentação mais específicos.
A tela de segmentos permite listar os **Matchers**/**Segmentos** salvos, uma
listagem de onde são utilizados, e bem como criar novos Segmentos.
**Matchers** podem ser usados *inline* ou salvos com um **nome específico**. A
principal diferença entre as duas abordagens é que um matcher salvo será
avaliado apenas uma vez, e seu resultado permanecerá consistente durante todo o
ciclo de solicitação. Isso significa que, uma vez que um matcher é avaliado como
`true` ou `false` para uma determinada visualização de página do usuário, esse
valor será mantido durante toda a solicitação.
Esse comportamento permite que você reutilize o **mesmo resultado do matcher em
várias variantes dentro da mesma página ou em lugares diferentes em seu site**.
Dessa forma, você garante um comportamento consistente e evita avaliações
redundantes da mesma condição.
Além disso, alguns matchers têm um comportamento `sticky`, o que significa que o
resultado do matcher pode ser armazenado na sessão do usuário e permanecer
consistente até o término da sessão. Isso é especialmente útil para testes A/B,
onde os usuários são atribuídos a uma variante específica e devem ter uma
experiência consistente durante a sessão.
Aproveitando os Matchers e suas capacidades, você pode criar experiências
dinâmicas e personalizadas para seus usuários, ao mesmo tempo em que otimiza o
desempenho, reduzindo avaliações redundantes e mantendo a consistência entre as
variantes.
## Testes A/B
Você pode criar **testes A/B** manualmente selecionando a condição
`Random Matcher` e configurando a porcentagem de tráfego a ser dividido.
Alternativamente, se você não estiver usando uma condição `Random Matcher`,
nosso botão "Publicar" solicitará automaticamente a criação de um novo teste. O
resultado é exatamente o mesmo que criar o teste manualmente.
## Criando segmentos
Para criar um segmento a ser usado em diferentes sites, basta entrar na operação
de "Create New Segment".
É possível:
* **Create template**: Cria um segmento que será disponibilizado na biblioteca
de segmentos. Isto significa criar uma base de código que definirá um conjunto
de propriedades e um programa para retornar dados.
* **Using a template**: Cria um segmento salvo a partir de uma base existente. O
nome será a identificação deste elemento.
A implementação padrão oferece um conjunto rico de seleções possíveis para uso,
mas é possível criar qualquer segmento que se baseie na requisição, contexto do
site ou propriedades definidas pelo usuário.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/advanced/seo
Como configurar meta-tags e media sharing no admin
O SEO (Search Engine Optimization) representa um conjunto de ações feitas ao
site para facilitar sua busca e indexação por robôs, especialmente de busca.
Nesta página configuramos parte desses elementos (meta-tags) que são utilizados
pelos buscadores, mas também por sistemas para geração da visualização de links
compartilhados.
Nesta edição, é possível configurar alterações que serão aplicadas a todo o
site.
Fique atento a algumas das configurações disponíveis para configuração do título
da página:
* Title: Título do site
* Title template: Base para títulos criados dinamicamentes por outros
componentes (no `app` de ecommerce, temos os blocos `SEOPLP` e `SEOPDP`)
E a configuração se o site deve, ou não, ser indexado (`Disable indexing`).
## Configurando SEO de uma página
Apesar da configuração global de SEO, é possível especializar o SEO de uma
página específica. Para isto, é preciso entrar na edição da página, e listar as
propriedades de SEO da página.
## Sitemap
O sitemap da deco é gerado automaticamente a partir da listagem de páginas.
Sites de ecommerce processam o sitemap recebido do backend para gerar um sitemap
válido.
## Robots.txt
O `robots.txt` representa um arquivo padrão usado por bots na internet para
definir como devem processar o seu site.
Para isto, é possível editar o arquivo no próprio admin:
O robots segue um formato bem definido e que deve ser respeitado para permitir o
processamento adequado do seu site.
```
User-agent: AIBadBot
Disallow: /
User-agent: Googlebot
Allow: /
User-agent: NomeDoBot
User-agent: NomeDoBot2
Disallow: /
Allow: /cgi-bin
Allow: /institucional
```
Cada diretiva (conjunto de regras para um bot), é feita por um (ou mais)
`User-agent`s, pelo menos uma regra de `allow` ou `disallow`, e outras regras
opcionais (a depender do bot).
Os valores para essas regras podem incluir `*` para representar todos ou
qualquer conjunto de bots ou paths.
> Com o crescimento de bots de AI generativas, nós não recomendamos liberar por
> padrão o acesso para qualquer bot e qualquer path. Uma configuração ideal:
> * para os buscadores (como google/bing/etc): liberar ao acesso a todos os
> paths, com algumas exceções
> * para todos os bots, barrar tudo exceto paths bem precisos ou orientados a
> AI, como páginas institucionais, ou mesmo pratileiras ou catalogos de
> produtos representativos para a AI
# null
Source: https://docs.deco.cx/pt/cms-capabilities/content/assets
Recursos digitais do site
Os `assets` representam bens digitais como as imagens que são carregadas na
infraestrutura da deco.
Esta é a tela de gerência desses recursos e, por ela, é possível adicionar novas
mídias digitais, bem como copiar a URL final do recurso, bem como apagar o que
foi carregado.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/content/blog
Adicionando um blog
O Blog representa um espaço para gestão de um blog no seu site. Nesta
documentação, vamos adicionar um blog ao seu site, que é um dos Apps do deco. Um
`App` permite que você adicione novas funcionalidades ao seu site de maneira
simples.
Para adicionar um app ao seu site, clique na guia Apps. Você verá todos os apps
disponíveis. Neste caso, vamos adicionar o App de Blog, que adiciona ao seu site
seções, integrações e funcionalidades para escrever e gerenciar posts de blog.
Clique no botão de alternância e o app será instalado no seu site.
Agora você pode gerenciar seu blog e adicionar posts, autores e categorias.
> Especificamente para o app de Blog, você pode acessar as funcionalidades do
> app através do seu próprio espaço. Para a maioria dos apps, suas funções e
> componentes serão exibidos nos outros espaços (seções, ações, carregadores,
> ...).
## Páginas de blog
O template de blog já apresenta `sections` e `pages` configuradas.
Caso tenha criado seu site a partir de outro template, recomendamos copiar estes
elementos do repositório do template de blog.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/content/pages
Aprenda como criar páginas na deco.cx sem precisar de código
A listagem de páginas de um site pode ser acessada na barra lateral em
`Content > Pages`.
Uma **Page** é um bloco fundamental na criação de um Site *deco.cx* que
normalmente terá várias Pages. Cada `Page` consiste em:
* **uma ou mais [Sections](https://deco.cx/docs/pt/concepts/section)** configuradas, que podem
ser consideradas como componentes modulares que compõem o conteúdo da página.
* **um nome:** um nome significativo para entender o que essa página representa.
Não afeta a interface do usuário ou os metadados da página, apenas exibido na
listagem de páginas do admin.
* **um path:** representa a URL que aquela página estará acessível para seus
usuários. Pode ser estático (por exemplo: `/posts`) ou dinâmico (por exemplo:
`/posts/:slug`, `/search/*`), seguindo o esquema
[URLPattern](http://mdn.io/urlpattern).
## Criar uma nova página
Clique em **Pages** no menu superior e você poderá ver todas as páginas
publicadas no site, juntamente com o *path* que elas são acessíveis aos seus
usuários.
> É possível duplicar ou apagar páginas usando as ações extras na listagem de
> páginas (ícone de 3 pontos).
Para criar uma nova página em seu site, **clique no botão Criar no canto
superior direito da lista de páginas**. Um formulário será aberto com os campo:
**nome**, **path** e **template**. Template permite criar uma página tomando o
conteúdo de outra como base (campo opcional).
Após criada, você será redirecionado para o editor de página. Agora é possível
editar e adicionar novas Sections disponíveis em seu site e configurar a página
do jeito que você quiser.
## Editar uma página
Para adicionar uma nova Section à página, clique no botão **Add Sections** no
editor e verifique todas as opções disponíveis.
Ao adicionar uma nova section, é possível selecionar sections que são globais ou
locais (obtidas da library). Há uma diferença entre elas:
* Uma section global já foi configurada e pode ser utilizada por 1 ou mais
páginas. Ao alterar a propriedade de uma section global, essa alteração é
refletida em todas as páginas que as usam
* Uma section local será configurada dentro da página, e só existe com essa
configuração nessa página (não é compartilhada entre outras páginas).
Ao selecionar uma section, será possível definir suas propriedades. Algumas das
propriedades podem pedir a seleção de uma imagem, texto, seleção de itens, ou
mesmo de um **loader**. Um **loader** é uma entidade que carrega dados e que
pode receber configurações (selecionando um loader da library) ou já estar
configurado (loaders salvos).
Além disso, é possível variar uma section a partir da seleção do ícone de
bandeira (🏳️).
## Variar uma Section
Uma variante permite que a section tenha outra configuração quando determinada
condição (**matcher**) é satisfeita. Essa condição pode ser algo já previamente
configurado (a partir de um **matcher** salvo) ou você poderá configurar a
partir de um elemento da biblioteca de matchers.
É bem comum criar variantes especialmente para campanhas ou eventos de tempo
limitado. Para isso, uma estratégia é configurar um matcher de data e hora.
A variante "default" representa a página a ser exibida quando nenhum matcher é
satisfeito.
> **Importante**: os matchers são testado na ordem que são colocados do primeiro
> (mais acima) até o último (default). Quando um matcher é satisfeito, ele é
> imeditamente executado e nenhuma outra condição posterior é testada,
> independente de qualquer outro matcher em seguida que possa satisfazer a
> condição configurada.
## Editar um SEO de uma página
O SEO de uma página segue o padrão definido no site. É possível especializar o
SEO de uma página editando o SEO a partir da opção de edição de SEO.
## Publicar alterações
A página será alterada a cada edição feita. Estas alterações são pertinentes ao
ambiente que você esteja trabalhando (inicialmente, staging). Uma alteração no
ambiente não é refletido no ambiente em produção até que essa alteração esteja
publicada.
## Variar uma página (segmentando uma páginas)
Uma variante permite criar uma visão diferente de uma página a partir de
condições específicas. Uma variante pode ser adicionada a partir do símbolo de
banderira (🏳️).
Adicione um "**Matcher**" que representa uma regra que será testada para avaliar
quais sections serão atendidas. No nosso exemplo, selecionamos um Matcher local
para selecionar um tipo de dispositivo e, mais especificamente, o desktop.
A variante é criada com todas as sections copiadas da página original. Cada
variante pode ter sections editadas de forma independente. Clique na variante
criada e altera as sections da forma que quiser. A variante "default" representa
a página a ser exibida quando nenhum matcher é satisfeito.
Quando você tem várias variantes em uma única página, a deco automaticamente
exibe a pré-visualização da variante selecionada por padrão. Se nenhuma variante
estiver selecionada, a deco mostra o que o usuário veria se fosse atribuído à
variante. Isso permite que você navegue entre as variantes selecionadas e
visualize como seria a experiência do usuário para cada variante.
Você também pode ter uma variante dentro de outra variante. Você pode usar
matchers diferentes ou uma combinação deles.
> **Importante**: os matchers são testado na ordem que são colocados do primeiro
> (mais acima) até o último (default). Quando um matcher é satisfeito, ele é
> imeditamente executado e nenhuma outra condição posterior é testada,
> independente de qualquer outro matcher em seguida que possa satisfazer a
> condição configurada.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/content/records
Records - Banco de dados embutido
A `deco` oferece um banco de dados embutido que pode ser usado como fonte de
dados para os componentes do site.
Nesta tela, é possível gerenciar esta base de dados, listando elementos da
tabela ou adicionando novos dados.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/content/releases
Ambientes de edição e evoluções do site
Na tela de releases, é possível avaliar os diferentes ambientes de edição
(`environment`) do site, bem como as diferentes publicações (`releases`)
realizadas. Cada ambiente de edição oferece um espaço único para que múltiplos
usuários possam fazer alterações e possa enviar tais alterações para produção
(para o endereço do site oficial).
Ao realizar qualquer alteração no site, o seletor de ambientes sinaliza que há
alterações realizadas no ambiente atual. O `Staging` é o ambiente padrão e
inicia sem alterações. Isto é indicado no canto superior direito, no seletor de
ambientes. O nome staging, sem um número associado e na cor verde, indica que o
ambiente atual não difere do ambiente em produção.
Para publicar um ambiente, é preciso ir na opção de `publish`. Nela, será
possível verificar as alterações realizadas, bem como realizar a publicação para
o endereço em produção. Observe que cada ambiente pode realizar mudanças e
alterações de forma independente. Antes de publicar uma alteração, ou mesmo
quando achar necessário, o usuário realizará um `Rebase`.
O processo de `rebase` se traduz em incorporar o estado atual do ambiente de
produção na próprio ambiente. Tenha em mente as seguintes dicas de uso sobre
ambientes:
* Para realizar um conjunto de alterações, faça isso num ambiente em separado.
Isto permite ver alterações que são específicas daquele ambiente.
* Por exemplo, crie um ambiente **home** para alterações na home, ou **header**
para alterações no header global, ou um ambiente **blackfriday** para
alterações especificas de um evento.
* Caso queira testar alterações, mas que serão descartadas, crie um ambiente
como **rascunho** ou **teste**.
* Ao começar a trabalhar em um ambiente, e também antes de publicar alterações,
faça **rebase** e teste a página. Isto garante que o ambiente atual terá o que
está em produção mais suas alterações realizadas.
Vamos dar um exemplo de mudanças em um cenário com dois ambientes: `staging` e
`matheus`. As seguintes ações foram realizadas:
1. Um, ou dois usuários, realizaram o total de duas mudanças no ambiente
`staging`
2. Um usuário realizou uma alteração no ambiente `matheus`. Neste momento, todos
os dois ambientes divergem entre si e divergem do ambiente em produção.
3. Uma publicação é feita a partir do ambiente staging. Neste momento, o estado
atual do `staging` e produção são iguais.
4. No ambiente `matheus` um usuário faz o rebase. Dessa forma, o ambiente
`matheus` incorpora as alterações que foram inseridas a partir de staging,
mas mantendo a alteração que existia antes.
5. Em seguida, é feita uma publicação a partir do ambiente `matheus`. Neste
momento, o ambiente `matheus` e produção apresentam o mesmo estado.
6. Por fim, `staging` faz um rebase, fazendo com que todos os ambientes estejam
no mesmo estado.
# Environment (ambientes de desenvolvimento)
Um ambiente representa um espaço de trabalho onde é possível realizar um
conjunto de alterações ou modificações que poderão ser publicadas. Todo ambiente
é compartilhável: ou seja, multiplos usuários podem fazer alterações no mesmo
ambiente, de forma que todas possam ser publicadas ao mesmo tempo.
O `Staging` é o ambiente padrão e inicia sem alterações. Isto é indicado no
canto superior direito, no seletor de ambientes. O nome staging, sem um número
associado e na cor verde, indica que o ambiente atual não difere do ambiente em
produção.
# Releases (Lançamentos)
`Releases` contém o histórico de todas as versões publicadas do seu site e
permite que você restaure para versões anteriores, se necessário.
## Passo a passo
1. Apenas o primeiro lançamento representa o estado atual no site. Procure a
versão para qual deseja retornar e acesse a operação de `Revert`.
2. Essa operação irá restaurar o código para o estado anterior, incluindo
alterações no estado da páginas e código do repositório.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/content/sections
Trabalhando com sections
As sections representam componentes que podem ser utilizadas para montar uma
página. Uma section é um componente Preact, ou seja, um elemento que transforma
algumas propriedades passadas para este componente em HTML.
Ao abrir as sections (barra lateral `Content > Sections`), você terá acesso a um
conjunto de sections salvas, a biblioteca de componentes e a possibilidade de
criar e salvar sections.
As diferentes categorias presentes na listagem são obtidas a partir do diretório
que a section se encontra ou da **App** na qual ela origina (uma **App** pode
importar diferentes sections).
A partir desta tela é possível:
* **Saved**: Listar as sections salvas
* **Library**: Listar e testar todas as sections disponíveis pra uso
* **Create new Section**: Criar novas Sections
## Alterar sections salvas
Uma **sections salva** representa um compoente que pode ser comparitlhado entre
várias páginas. Elementos como **Footer** e **Header** podem ser compartilhado
entre diferentes páginas, da forma que estes elementos podem ter suas
propriedades configuradas apenas uma vez.
As sections salvas podem ser configuradas a partir desta tela, de forma afetar
todas as sections do sistema. Ao clicar em uma section salva é possível alterar
suas propriedades configuradas anteriormente.
## Configurando uma section
Ao selecionar uma section, será possível definir suas propriedades. Algumas das
propriedades podem pedir a seleção de uma imagem, texto, seleção de itens, ou
mesmo de um **loader**. Um **loader** é uma entidade que carrega dados e que
pode receber configurações (selecionando um loader da library) ou já estar
configurado (loaders salvos).
## Listar e testar demais sections
Ao listar as sections na library, e clicar em uma section, você passa a ter
acesso a uma visualização da Section, bem como acesso ao código original daquele
elemento. É também possível editar o código, para testar alterações na
funcionalidade do componente.
Na barra lateral a direita, é possível acessar:
* `🌐` Visuzalização do elemento
* `☰` Formulário com propriedades
* `{}` Descrição textual das propriedades
* `>` Editor de código
* `🖥️` Logs relacionados a visualização da section
* `✨` Decopilot: IA para alteração do código
## Criar nova Section
É possível criar uma section salva (um componente compartilhável entre várias
páginas) ou a base (template) de uma section.
* **New template**: Cria uma section que será disponibilizada na biblioteca de
componentes. Isto significa criar uma base de código que definirá um conjunto
de propriedades e um programa para gerar o HTML associado.
* **Using a template**: Cria uma section salva a partir de uma base existente. O
nome será a identificação deste elemento entre as diferentes páginas.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/home
Home: gestão de times, sites e perfil do usuário
A `home` representa o espaço inicial do usuário. A partir desta tela, é possível
acessar sites, times, bem como a própria documentação da deco.
## Command Bar
Na home, e ao longo do uso do admin, uma `command bar` estará sempre disponível
na barra superior da tela. A barra de comando opera de acordo com o contexto
aberto. Na `home`, ela permite buscar, e abrir, sites e times do usuário.
Além disso, é possível realizar comandos específicos. Na `home` estão
disponíveis os comandos:
* **/open**: para abrir sites ou times (comando padrão ao selecionar um time ou
site a partir da busca)
* **/delete**: para apagar sites ou times
## Perfil
Além da `command bar`, é sempre possível acessar o perfil do seu usuário a
partir de qualquer espaço no admin. Para isto, acesse a foto do seu usuário no
canto superior direito.
Nele, é possível definir configurações a respeito de seu perfil (incluindo sua
foto), detalhes de pagamento (para usuários que executam tarefas), e uma API key
para uso do admin.
### API Key (Dev)
A API Key permite executar operações no admin (loaders e actions), com as
permissões do seu usuário. Na requisição para loaders/actions do admin, defina o
header `x-api-key` que é disponibilizado nesta tela.
## Times
A gestão de time permite a configuração de:
* **Sites**: Listagem dos sites do time, bem como capacidade de mover, apagar e
abrir site
* **Members**: Listagem dos membros do time, permitindo a gerência de papéis e o
convite de membros
* **Billing**: Permite a contratação e gestão do tipo de conta para o time
* **Settings**: Altera o nome do time ou apaga o próprio time
# null
Source: https://docs.deco.cx/pt/cms-capabilities/management/apex-domains
Como redirecionar domínio sem www
## O que é domínio apex?
Domínio apex é o termo utilizado para domínio raiz, sem subdomínio.
Exemplo:
* `www.example.com.br` -> Subdomínio
* `loja.example.com.br` -> Subdomínio
* `example.com.br` - Domínio Apex
## Posso apontar um site deco.cx para o domínio apex?
Não, ainda não é possível apontar um site deco.cx para o seu domínio apex.
Por isso, criamos uma solução fácil de redirecionamento, para que os acessos ao
domínio Apex não sejam perdidos.
## Como redirecionar um domínio apex na deco.cx?
1 - No painel do seu site na deco.cx, acesse a página de Configurações.
2 - Clique em "Adicionar domínio existente"
3 - Insira o seu domínio apex (sem subdomínio):

4 - Defina para qual subdomínio redirecionar:

5 - Agora, você verá os apontamentos que devem ser feitos na sua plataforma de
hospedagem de domínio:

6 - Após realizar as configurações, clique em Validar Domínio.
A etapa de validação é essencial para o funcionamento e ela depende da
propagação do DNS configurado no serviço de hospedagem.
No geral, a propagação ocorre dentro algumas horas, mas pode levar até 48 horas
em alguns casos.
# null
Source: https://docs.deco.cx/pt/cms-capabilities/management/custom-domains
Adicionando domínios próprios
# Tópicos
1. O que é um domínio próprio?
2. Adicionando um domínio
* Requisitos
* Adicionando um domínio no admin
3. Validando o domínio adicionado
* Passo-a-passo
* Testando sua configuração
4. Erros comuns
# O que é um domínio próprio?
Cada site deco recebe um domínio público na qual ela é acessível, como o domínio
`your.deco.site` que é usado no endereço `https://your.deco.site`. No entanto, é
comum contratar um domínio próprio para fortalecer a marca ou facilitar o acesso
a um site.
A deco não oferece (ainda) um servidor próprio de nomes de domínios, mas é
possível contratar esse serviço por outras empresas como godaddy, google e
cloudflare. Do ponto de vista técnico, é importante que esse servidor permita a
criação de apontamentos do tipo `CNAME`. É preciso ter cuidado pois alguns
serviços de hospedagem podem oferecer o serviço de nomes, mas não permitir este
tipo de configuração!
# Adicionando um domínio próprio
## Requisitos
Para adicionar um domínio:
* o site precisa ter um domínio `deco.site` oferecido pela deco
* o usuário precisa ser administrador do site
* o usuário precisa contratar um domínio próprio em um servidor de nomes que
permita configuração de `CNAME`
* o usuário ou administrador do domínio próprio precisa criar um apontamento
`CNAME` indicado na etapa de validação
* APENAS caso o domínio já tenha algum apontamento `CAA`, é preciso adicionar
novos apontamentos
## Antes de adicionar um domínio
Pode ser necessária alguma configuração adicional em seu site dependendo da
integração utilizada.
Caso o domínio tenha algum apontamento `CAA`, é preciso adicionar novos domínios
para que possamos gerar o certificado do seu novo domínio. Importante:
`caso seu domínio não tenha apontamentos CAA, esta etapa não é necessária (e não é recomendada)`.
É possível verificar se o domínio tem esses apontamentos através da ferramenta
[Google Admin Toolbox Dig](https://toolbox.googleapps.com/apps/dig/#CAA/) ou o
comando `dig seudominio.com.br caa +short`. Caso a consulta não retorne dados
(`Record not found!`), ignore esta etapa.
Caso seu site tenha certificados, é preciso adicionar os registros abaixo,
especialmente os dois últimos (`pki.goog`). Adicione no domínio do seu site (ou
`@` como nome do campo).
```
0 issue "digicert.com; cansignhttpexchanges=yes"
0 issuewild "digicert.com; cansignhttpexchanges=yes"
0 issue "sectigo.com"
0 issuewild "sectigo.com"
0 issue "letsencrypt.org"
0 issuewild "letsencrypt.org"
0 issue "pki.goog; cansignhttpexchanges=yes"
0 issuewild "pki.goog; cansignhttpexchanges=yes"
```
Alguns provedores de domínios não aceitam o CAA com `cansignhttpexchanges`,
neste caso, configure sem essa propriedade:
```
0 issue "digicert.com"
0 issuewild "digicert.com"
0 issue "sectigo.com"
0 issuewild "sectigo.com"
0 issue "letsencrypt.org"
0 issuewild "letsencrypt.org"
0 issue "pki.goog"
0 issuewild "pki.goog"
```
Veja mais instruções no seu provedor de domínios em como adicionar esses campos.
## Adicionando um domínio no admin
1. Entre na página inicial do site, e navegue para a aba de Configurações.

2. Em Configurações, na listagem de Domínios, verifique que há um domínio
`deco.site` e adicione um domínio existente. **Caso não tenha um domínio
`deco.site`, entre em contato conosco**.
3. Adicione o domínio próprio do site no modal aberto. O domínio deve ser apenas
o nome, sem protocolo (http/https) ou barras. Aguarde o processo de
configuração inicial.

4. Depois da adição, o domínio está registrado na deco, mas ainda não é
operante. É preciso agora fazer o setup do domínio. Em `...`, clicando em
setup, haverá instruções de configuração.
5. Adicione a configuração de domínio no seu servidor de domínios. Isto
representa um apontamento `CNAME` do domínio própio, para o domínio da deco.
No exemplo, isto representa um apontamento do domínio `www.example.com` para
`startest.deco.site`.

6. Uma vez configurado, clique em validar configuração para que a deco valide se
o apontamento foi corretamente realizado. **Importante: O domínio continuará
no estado de em espera por validação até que o apontamento seja realizado na
nossa infraestrutura**.
7. Aguarde alguns minutos e teste acessar seu domínio no browser.
# Erros Comuns
## O domínio não é validado
Verifique se o mesmo foi cadastrado corretamente no servidor de nomes. Use uma
ferramenta como o ][DNS da google](https://dns.google/) para verificar se há um
registro de `CNAME` apontando o domínio corretamente para um domínio
`deco.site`. Alguns provedores de domínios podem levar até 12 horas para
efetivar o novo apontamento.
## Após a validação, as configurações ainda exibem meu domínio como "Awaiting"
Por vezes, o domínio pode fazer a geração de certificados mesmo depois de sair
da tela de validação. No entanto, mesmo nesse caso, o domínio próprio pode já
estar operante.
## Quero transferir o apex (nome raíz) para a deco.
Atualmente, não é possível fazer esse apontamento na deco.
## Outras situações
Procure o discord da deco caso precise de ajuda!
# null
Source: https://docs.deco.cx/pt/concepts/action
Uma Action na deco.cx é uma função que modifica dados.
Uma **Action** no deco.cx é uma função em typescript que **modifica** dados
dentro da aplicação. As **Action** são acionadas por *interações* específicas do
**usuário** ou **eventos** e são responsáveis por atualizar o estado da
aplicação de acordo. Ao contrário dos **Loaders**, que buscam dados de fontes
externas, as **Action** concentram-se em modificar os dados já presentes na
aplicação. Elas podem realizar operações como **atualização**, **criação** ou
**exclusão** de dados com base na lógica especificada. As **Action**
proporcionam *controle* preciso e flexibilidade sobre a mutação de dados e
integram-se perfeitamente a outros blocos, como os **Loaders**, para permitir um
fluxo contínuo de dados na aplicação.
As **Action**, assim como os **Loaders**, são implementadas como funções em
typescript e estão localizadas na pasta `/actions/` do seu projeto. Elas podem
ser invocadas em resposta a interações do usuário, envios de formulários ou
qualquer outro gatilho definido. Ao encapsular a lógica de mutação de dados nas
**Action**, os desenvolvedores podem gerenciar e rastrear as alterações feitas
no estado da aplicação, proporcionando aos usuários experiências dinâmicas e
interativas.
## Código de exemplo
Esta é a implementação da Action `newsletter/subscribe.ts`:
```tsx
import { AppContext } from "../../mod.ts";
export interface Props {
email: string;
name?: string;
page?: string;
part?: string;
campaign?: string;
}
const action = async (
props: Props,
_req: Request,
ctx: AppContext,
): Promise => {
const { vcsDeprecated } = ctx;
const form = new FormData();
const {
email,
name = "",
part = "newsletter",
page = "_",
campaign = "newsletter:opt-in",
} = props;
form.append("newsletterClientName", name);
form.append("newsletterClientEmail", email);
form.append("newsInternalPage", page);
form.append("newsInternalPart", part);
form.append("newsInternalCampaign", campaign);
await vcsDeprecated["POST /no-cache/Newsletter.aspx"]({}, {
body: form,
});
};
export default action;
```
[Fonte](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/vtex/actions/newsletter/subscribe.ts#L1C1-L37C23)
## Leitura recomendada
* [Buscando dados de API](https://deco.cx/docs/pt/developing-guide/fetching-data)
* [Invocando funções através da API](https://deco.cx/docs/pt/developing-capabilities/islands/fetching-data-client)
# null
Source: https://docs.deco.cx/pt/concepts/app
Apps - Capacidades de Negócios para os seus Sites deco
As Apps são poderosos conjuntos de capacidades de negócios que podem ser
importados e configurados em sites deco. Uma App na deco é essencialmente uma
**coleção** de vários **componentes**, como **ações**, **seções**,
**carregadores**, **fluxos de trabalho**, **manipuladores**, ou quaisquer outros
elementos deco que podem ser usados para aprimorar a funcionalidade dos seus
projetos deco.
## Visão Geral
Na deco, os Apps funcionam como blocos de construção modulares que encapsulam
recursos ou capacidades específicas. Eles permitem que os desenvolvedores
empacotem e compartilhem funcionalidades específicas do negócio em diferentes
projetos, tornando mais fácil a manutenção e a expansão dos seus sites deco.
Ao executar o comando `deno run -Ar https://deco.cx/start` no terminal, você
pode começar a desenvolver um App do zero e colocá-lo em funcionamento
rapidamente.
## Configuração da App
Cada App pode ser configurado com parâmetros específicos, tornando-o versátil e
adaptável a diferentes casos de uso. Os desenvolvedores podem importar e
configurar Apps em seus sites deco, permitindo uma integração perfeita e
personalização da funcionalidade.
## Suporte a Monorepo
Os deco Apps podem ser gerenciados em um monorepo, proporcionando um local
centralizado para armazenar e organizar vários Apps. Essa abordagem agiliza o
processo de desenvolvimento e permite um controle de versão e manutenção
eficiente dos Apps.
## Primeiros Passos
Para criar seus próprios deco Apps, siga estes passos:
1. Execute o comando `deno run -Ar https://deco.cx/start` para inicializar um
novo deco App.
2. Defina as funcionalidades ou componentes que você deseja empacotar na app.
3. Organize as funções, seções, carregadores ou outros componentes deco dentro
do diretório do App.
4. Configure o App para aceitar parâmetros e ser personalizável dentro do deco
Admin.
5. Exporte o App para ser usado em outros projetos deco.
## Importando e Desinstalando Apps
Para usar um deco App no seu site deco, você pode executar os seguintes
comandos:
1. Para instalar o App:
```sh
deno task install $APP_URL
```
Substitua `$APP_URL` pelo local do diretório ou URL HTTP do App.
2. Para desinstalar o App:
```sh
deno task uninstall $APP_URL
```
Substitua `$APP_URL` pelo local do diretório ou URL HTTP do App.
## Observação
Os deco Apps fornecem um mecanismo poderoso para criar e compartilhar
capacidades de negócios reutilizáveis em seus projetos deco. Ao organizar
componentes em Apps modulares, você pode melhorar significativamente a
manutenção e a escalabilidade dos seus sites deco. Sinta-se à vontade para
explorar as Apps existentes e criar os seus próprios para agilizar o processo de
desenvolvimento e construir projetos deco robustos.
## Leitura Recomendada
* [Conceitos da deco: Entendendo Seções](https://deco.cx/docs/pt-br/concepts/section)
* [Buscando Dados de APIs](https://deco.cx/docs/pt-br/developing-guide/fetching-data)
* [Invocação de Funções no Lado do Cliente](https://deco.cx/docs/pt-br/developing-capabilities/islands/fetching-data-client)
# null
Source: https://docs.deco.cx/pt/concepts/block
O Block empoderam o ecossistema da deco
## Visão Geral
Imagine poder **serializar** uma função e salvá-la em um **banco de dados**. E
se essa função pudesse ser combinada com várias opções diferentes? Como isso
mudaria a forma como você desenvolve aplicações web?
No deco, tudo gira em torno dos **Blocks** (blocos). Esses Blocks são funções
serializadas que podem ser combinadas perfeitamente, permitindo possibilidades e
personalizações ilimitadas.
Com o deco, você tem a flexibilidade de usar um `Inline Block` (bloco em linha),
onde você pode criar e usar Blocks instantaneamente, ou criar um Block com um
nome específico e salvá-lo para uso futuro, conhecido como `Saved Block` (bloco
salvo).
Usando o *deco*, os desenvolvedores têm a capacidade de definir **Blocks**
(blocos). Esses **Blocks** são construídos em cima do Deno, fornecendo
*"capacidades encapsuladas"* reutilizáveis e configuráveis que podem ser
combinadas para criar e implantar aplicações web robustas em questão de minutos.
Eles permitem que os desenvolvedores criem unidades de funcionalidade modulares
e combináveis. Com os Blocks, você pode facilmente combinar e integrar
diferentes capacidades para construir aplicações complexas e personalizadas
adaptadas às suas necessidades específicas.
## Personalizando a Interface do Admin
O próprio Admin UI do deco é construído usando **Blocks**, tornando-o altamente
personalizável e expansível. Os desenvolvedores têm a liberdade de compor suas
próprias interfaces personalizadas de administração de experiência digital que
se adequam perfeitamente aos requisitos de seus usuários de negócios. Com o
deco, você tem total controle sobre sua interface de administração, garantindo
que ela atenda precisamente às suas necessidades exclusivas.
## Biblioteca Visual: Explore e Personalize os Blocks
Além do poderoso framework de **Blocks**, o deco oferece uma *abrangente
biblioteca visual* que permite que você **navegue por seus blocos**. Essa
biblioteca visual capacita você a explorar várias opções e configurações para os
componentes e recursos do seu site.
Com a Biblioteca Visual, você tem a flexibilidade de personalizar e ajustar os
Blocks de acordo com seus requisitos específicos. Você pode editar e visualizar
facilmente os Blocks com diferentes configurações, garantindo que eles se
alinhem perfeitamente com os elementos visuais e funcionais desejados.
# null
Source: https://docs.deco.cx/pt/concepts/loader
Um Loader na deco.cx é uma função que retorna os dados necessários para um Site.
Um **Loader** em *deco.cx* é uma função Typescript que retorna tipicamente os
dados necessários em uma [Section](https://deco.cx/docs/pt/concepts/section). Essas funções são
executadas antes da renderização de cada página e seu principal objetivo é
**buscar dados de fontes externas**, transformá-los se necessário e
**fornecê-los às Seções do site que precisam.** Os Loaders podem ser usados para
buscar dados de APIs, bancos de dados ou qualquer outra fonte externa. As
implementações locais de Loaders vivem na pasta `/loaders` do seu projeto, porém
é possível [Instalar novas apps](https://deco.cx/docs/pt/getting-started/installing-an-app) que
contém outros loaders.
Além de buscar dados, os Loaders na *deco.cx* **também podem exportar um tipo de
Props Typescript**, o que permite que sejam configurados no
[Admin](https://deco.cx/admin) assim como as
[Sections](https://deco.cx/docs/pt/concepts/section). Isso significa que os usuários de negócio
podem configurar detalhes sobre como o Loader irá operar, como **configurar
filtros** ou **passar parâmetros para APIs.** Ao tornar os Loaders configuráveis
dessa maneira, fica mais fácil gerenciar os dados que fluem para as Sections e
garantir que o Site esteja exibindo as informações corretas para os visitantes.
Outro benefício dos Loaders na *deco.cx* é que **vários loaders podem retornar o
mesmo tipo de dados**. Isso permite que as [Sections](https://deco.cx/docs/pt/concepts/section)
que recebem, por exemplo, um *array* de Produtos canônico obtenham dados de
diferentes Loaders, dependendo da configuração do usuário. Isso significa que as
UIs podem ser reutilizadas em [Sites](https://deco.cx/docs/pt/concepts/site) ou entre times,
facilitando o gerenciamento e a escala do seu projeto.
> Todas as Sections para lojas de *ecommerce* criadas por *deco.cx* na
> [Fashion](https://github.com/deco-sites/fashion) usam um tipo de Produt
> canônico e também cada Loader que se conecta às APIs dos *ecommerce
> providers*. Isso significa que você pode reutilizar a mesma UI para mostrar
> dados de diferentes locais, dependendo da configuração.
## Código de exemplo
Esta é a implementação do Loader `shopify/loaders/ProductList.ts`:
```tsx
import type { Product } from "../../commerce/types.ts";
import { AppContext } from "../../shopify/mod.ts";
import { ListProducts } from "../utils/storefront/queries.ts";
import {
ListProductsQuery,
ListProductsQueryVariables,
} from "../utils/storefront/storefront.graphql.gen.ts";
import { toProduct } from "../utils/transform.ts";
export interface Props {
/** @description search term to use on search */
query: string;
/** @description total number of items to display */
count: number;
}
/**
* @title Shopify Integration
* @description Product List loader
*/
const loader = async (
props: Props,
_req: Request,
ctx: AppContext,
): Promise => {
const { storefront } = ctx;
const count = props.count ?? 12;
const query = props.query || "";
const data = await storefront.query<
ListProductsQuery,
ListProductsQueryVariables
>({
variables: { first: count, query },
...ListProducts,
});
// Transform Shopify product format into schema.org's compatible format
// If a property is missing from the final `products` array you can add
// it in here
const products = data?.products.nodes.map((p) =>
toProduct(p, p.variants.nodes[0], new URL(_req.url))
);
return products ?? [];
};
export default loader;
```
[Fonte](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/shopify/loaders/ProductList.ts#L1)
## Leitura recomendada
* [Buscando dados de API](https://deco.cx/docs/pt/develping/fetching-data)
* [Invocando um loader através da API](https://deco.cx/docs/pt/developing-capabilities/islands/fetching-data-client)
# null
Source: https://docs.deco.cx/pt/concepts/matcher
Um Matcher na deco é uma função que retorna um booleano
## Matchers: Potencializando as Variants
Os **Matchers** são blocos essenciais no deco que desempenham um papel
fundamental ao potencializar as [Variants](https://deco.cx/docs/pt/getting-started/variants).
Eles permitem que você avalie condições específicas e segmente seu público com
base em vários critérios. Ao aproveitar os Matchers, você pode criar
experiências personalizadas e dinâmicas para seus usuários. Ao criar um novo
**Matcher Block**, você pode chamá-lo de [Segmento](https://deco.cx/docs/pt/concepts/segment).
### Compreendendo os Matchers
No deco, os **Matchers** são criados usando *funções* dentro do código do seu
site. Eles são ferramentas poderosas que permitem que você defina condições e
avalie se um usuário pertence a um determinado segmento. Os Matchers servem como
base para segmentar grupos específicos de usuários e personalizar o conteúdo com
base em suas características ou comportamentos.
Os **Matchers padrão** estão prontamente disponíveis no deco e abrangem uma
variedade de condições comuns, como características do usuário, data e horário,
tipo de dispositivo, localização geográfica e seleção aleatória (testes A/B).
Esses Matchers predefinidos oferecem *flexibilidade* e permitem que você
personalize as variações de conteúdo com base nessas condições.
No entanto, o poder dos Matchers vai além das opções padrão. O deco oferece a
capacidade de criar **Matchers personalizados** para atender às necessidades
específicas do seu negócio. Com Matchers personalizados, você pode estender a
funcionalidade do deco para integrar fontes de dados externas, como buscar dados
de um sistema Salesforce ERP, e usar esses dados para determinar o segmento ao
qual um usuário pertence.
### Matchers Nativos
| Matcher | Casos de Uso Comuns | Sticky |
| -------------- | ----------------------------------------------------------------------------------------------- | ------- |
| Random Matcher | Testar A/B na página com 50% do tráfego | session |
| Cron Matcher | Alterar uma página toda sexta-feira entre 10h e 11h | none |
| Date Matcher | Criar a página da Black Friday/ Agendar banners para aparecerem em datas e horários específicos | none |
| Device Matcher | Exibir uma página diferente com base no dispositivo do usuário | none |
### Desenvolvendo um Novo Matcher
Em seu repositório, os Matchers estão localizados na pasta `matchers`, assim
como as seções e loaders. Vamos criar um novo matcher chamado `MeuMatcher.ts`
para ilustrar o processo.
A assinatura do nosso matcher seguirá a seguinte estrutura:
```ts
import { MatchContext } from "deco/blocks/matcher.ts";
export interface Props {
}
/**
* @title Meu Matcher
*/
export default function MeuMatcher(
props: Props,
ctx: MatchContext,
) {
return true;
}
```
No exemplo acima, a função `MeuMatcher` aceita `props` como entrada, permitindo
que você passe quaisquer dados necessários para o matcher. Além disso, ela
recebe um objeto `ctx` do tipo `MatchContext`, que contém as informações da
solicitação. Você tem a flexibilidade de realizar as operações desejadas dentro
da função do matcher e retornar um valor booleano com base na avaliação.
Vamos dar uma olhada no exemplo `MatchDate` da biblioteca do deco:
```ts
/**
* @title Por início
*/
export interface Props {
/**
* @format date-time
*/
start?: string;
/**
* @format date-time
*/
end?: string;
}
/**
* @title Matcher de Data
*/
const MatchDate = (props: Props) => {
const now = new Date();
const start = props.start ? now > new Date(props.start) : true;
const end = props.end ? now < new Date(props.end) : true;
return start && end;
};
export default MatchDate;
```
Neste exemplo, a função `MatchDate` atua como um Matcher. Ela aceita `props`
como entrada, que inclui as propriedades `start` e `end`. A função avalia se a
data atual está dentro do intervalo de datas especificado. Se nenhum valor de
`start` ou `end` for fornecido, ele será considerado `true`. A função
`MatchDate` retorna um valor booleano com base na avaliação.
Os
Matchers também podem ter um comportamento "sticky", o que é particularmente
útil para cenários de testes A/B. Para tornar um Matcher "sticky" na sessão do
usuário, você pode exportar uma constante chamada `sticky` com o valor
`"session"`, conforme mostrado abaixo:
```ts
export const sticky = "session";
```
Aqui está um exemplo de implementação do `MatchRandom` usando a funcionalidade
de sessão "sticky":
```ts
/**
* @title Teste A/B {{{percentage traffic}}}
*/
export interface Props {
traffic: number;
}
// Uma vez selecionado, a sessão reutilizará o mesmo valor
export const sticky = "session";
/**
* @title Matcher Aleatório
*/
const MatchRandom = ({ traffic }: Props) => {
return Math.random() < traffic;
};
export default MatchRandom;
```
No exemplo `MatchRandom`, a função matcher `MatchRandom` aceita `traffic` como
prop, representando a porcentagem de tráfego que deve corresponder à condição.
Ao gerar um número aleatório entre 0 e 1, a função determina se o valor gerado é
menor que a porcentagem `traffic` especificada. O Matcher retorna `true` ou
`false` com base nessa avaliação.
Os Matchers oferecem grande flexibilidade para personalizar e estender a
funcionalidade do deco para atender às suas necessidades específicas. Com a
capacidade de criar Matchers personalizados, você pode integrar fontes de dados
externas, realizar cálculos complexos e implementar lógicas intrincadas para
determinar a segmentação do usuário e fornecer experiências personalizadas.
### Aproveitando o Poder dos Matchers nas Variants
Os **Matchers** são a base das Variants no deco. Ao *combinar Matchers com
diferentes condições*, você pode criar variações de conteúdo direcionadas para
segmentos de usuários específicos. As **Variants** permitem que você modifique e
personalize o conteúdo dinamicamente com base na avaliação dos **Matchers**.
Ao configurar as **Variants**, você pode selecionar o Matcher apropriado para
cada segmento e definir as condições que determinam se um usuário pertence a
esse segmento. Ao utilizar Matchers nas Variants, você pode ajustar a
experiência do usuário, otimizar a entrega de conteúdo e fornecer interações
personalizadas.
# null
Source: https://docs.deco.cx/pt/concepts/section
Uma Section representa um elemento de UI configurável para um Site deco.cx.
As Sections são **componentes de UI criados com
[Preact](https://preactjs.com/)** que pode receber `props` configuradas por
usuários no Admin da *deco.cx*. As implementações locais de Section vivem na
pasta `sections/` no código do Site, porém é possível
[Instalar novas apps](https://deco.cx/docs/pt/getting-started/installing-an-app).
Alguns exemplos de Section para uma loja de ecomemerce seriam:
* **ProductShelf.tsx:** exibe uma prateleira com imagem, título e preço.
* **Header.tsx:** exibe o cabeçalho padrão da loja, contendo logotipo,
categorias de menu e links para carrinho e login.
* **Banner.tsx:** exibe imagem, texto e alguns *Call to action* para campanha ou
departamento específico.
## Interatividade
Observe que as seções são executadas **somente no lado do servidor**, portanto,
gerenciamento de estado e ciclo de vida como `useState`, `useEffect` e callbacks
como `onClick`, `onInput` não irão funcionar. Para que funcionem, você precisará
usar [Islands](https://fresh.deno.dev/docs/concepts/islands).
No Admin da *deco.cx* é possível interagir com as Sections em dois locais:
* **Library:** permite que desenvolvedores configurem as propriedades das
Section e visualizaem automaticamente a UI renderizada. (Funciona semelhante
ao [Storybook](https://storybook.js.org/))
* **Pages:** Permite que a Section seja adicionada à Pages no Site, sendo também
configuráveis por lá.
## Leitura adicional
* [Tutorial: Codificando uma nova seção](https://deco.cx/docs/en/developing-guide/hello-world)
* [Desenvolvendo: Seções personalizáveis](https://deco.cx/docs/en/developing-guide/editable-sections)
# null
Source: https://docs.deco.cx/pt/concepts/segment
Um Segment na deco é um Matcher configurado juntamente com uma Variant
## Segmento: Direcionando Grupos Específicos de Usuários
No Deco, um **Segmento** se refere a um grupo específico ou subset de usuários
que atendem a certas condições ou critérios. Segmentos são uma ferramenta
poderosa que permite direcionar e personalizar o conteúdo para grupos de
usuários específicos, proporcionando experiências sob medida e otimizando a
entrega de conteúdo.
### Compreendendo os Segmentos
Segmentos são definidos por [Matchers](https://deco.cx/docs/pt/concepts/matchers), que avaliam
condições e determinam se um usuário pertence a um segmento específico. Matchers
podem considerar vários fatores, como características do usuário, data e
horário, tipo de dispositivo, localização geográfica e muito mais. Ao aproveitar
os Matchers, você pode criar variações de conteúdo dinâmicas e personalizadas
com base nessas condições.
### Utilizando os Segmentos
Segmentos desempenham um papel crucial em várias áreas do Deco, especialmente no
contexto de [Variants](https://deco.cx/docs/pt/getting-started/variants). Variantes permitem
criar variações de conteúdo e personalizar a experiência do usuário com base em
diferentes segmentos. Ao combinar Matchers com diferentes condições, você pode
direcionar grupos específicos de usuários e fornecer conteúdo personalizado para
melhorar o envolvimento e a satisfação.
Segmentos oferecem grande flexibilidade e permitem definir diferentes
estratégias de direcionamento com base em seus objetivos específicos e
características do público. Seja conduzindo testes A/B, exibindo conteúdo
diferente com base nas características do usuário ou personalizando experiências
com base em localização ou tipo de dispositivo, Segmentos capacitam você a
otimizar o desempenho do seu site e fornecer uma jornada personalizada ao
usuário.
Com a capacidade de definir e utilizar Segmentos no Deco, você pode criar uma
experiência do usuário altamente direcionada e envolvente, melhorando a
satisfação do usuário e alcançando seus objetivos de negócios.
Lembre-se de que Segmentos são definidos por Matchers, portanto, compreender
como os Matchers funcionam e criar Matchers personalizados que atendam aos seus
requisitos específicos permitirá que você aproveite efetivamente o poder dos
Segmentos no Deco.
# null
Source: https://docs.deco.cx/pt/decopilot/assistant
Decopilot como seu assistente de código
## Decopilot: Seu Assistente de Código
Como seu assistente, o Decopilot pode ajudar a melhorar e desenvolver seu site.
Abaixo, você pode ver diferentes exemplos de uso, mas sinta-se à vontade para
explorar o poder da IA. Para a geração de código, o Decopilot suporta tanto
texto com a solicitação desejada quanto a inserção de imagens locais. Em ambos
os casos, você pode escolher **aceitar as alterações**, **descartar** ou
**recriar o código fornecido.**
### Criando Blocos
Blocos são um dos conceitos mais importantes na deco.cx, então o Decopilot está
pronto para ser chamado para criar qualquer um desses componentes. É só pedir!
Desde loaders e actions até sections, o Decopilot perguntará se pode prosseguir
com o processo de criação ou não. Aqui está um exemplo de como funciona com
sections:
> Prompt: Crie uma section dizendo Olá Mundo!

### Criando e Editando Código
Você pode explorar a geração e edição de código com base no seu código atual e
na criação de novos componentes com o Decopilot. Por exemplo, ao usar o prompt:
> Prompt: Crie um Hero dizendo Hello World em tons de verde.
Após gerar o código, o Decopilot substitui o código usado, e você pode ver o
resultado na pré-visualização.

### Criando e Editando com Base em uma Imagem
Se você deseja usar uma imagem como inspiração, o Decopilot pode reproduzi-la ao
receber uma imagem local em um dos formatos suportados (JPEG, PNG, GIF e WebP)
junto com a solicitação do que fazer. Aqui está um exemplo de prompt:
> Prompt: Reproduza este componente para mim.

### Explicar e Corrigir Erros
Para ajudar ainda mais no processo de desenvolvimento, o Decopilot pode ajudar a
explicar algo para você ou até mesmo corrigir erros no seu código. Exemplo de
prompt:
> Prompt: O que este código faz?

### Analisar Desempenho
Seu assistente de código pode ser útil para consultar o desempenho do seu site e
fornecer feedback sobre como melhorá-lo. Aqui está um exemplo de prompt:
> Prompt: Como está o desempenho do meu site?
## Conclusão
Com base nas funcionalidades apresentadas, o potencial do Decopilot para
simplificar e acelerar o desenvolvimento de código é evidente.
[Experimente agora](https://admin.deco.cx/) e descubra como ele pode transformar
sua experiência de programação, tornando-a mais eficiente e produtiva!
# null
Source: https://docs.deco.cx/pt/decopilot/how-to-access
Como acessar o decopilot
## Introdução
O Decopilot é uma ferramenta de geração de código projetada para acelerar ainda
mais o processo de criação de sites. Buscando combinar a praticidade do uso de
inteligência artificial com a agilidade proporcionada pelo
[Admin da Deco](https://admin.deco.cx/) para o desenvolvimento de aplicações
web, o Decopilot oferece a liberdade para criar um site e seu conteúdo em
questão de minutos, enquanto auxilia você na identificação e correção de
eventuais erros durante o desenvolvimento.
## Como acessar
Após [criar seu site](https://deco.cx/docs/pt/getting-started/creating-a-site),
abra um arquivo de código em qualquer section do seu site. Você pode fazer isso
através da barra de pesquisa do nosso CMS ou clicando no ícone de código como
mostrado abaixo:

Na barra lateral direita você poderá acessar o decopilot conforme a imagem:

Pronto! Agora você pode experimentar as funcionalidades do nosso decopilot. Para
isso, vale a pena acessar o
[Assistant](https://deco.cx/docs/pt/decopilot/assistant).
# null
Source: https://docs.deco.cx/pt/developing-capabilities/analytics
TODO
## Enviando eventos para o dataLayer
O `dataLayer` é a camada de dados utilizada pelo Google Tag Manager ou Google
Tag (utilizado pelo Google Analytics) para gerenciar os eventos dos pixels que
estão configurados na tag.
Em um projeto deco.cx existe uma
[sdk/analytics.ts](https://github.com/deco-sites/fashion/blob/main/sdk/analytics.tsx)
que contem a função **sendEvents**, que recebe um objeto do tipo
[AnalyticsEvent](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/commerce/types.ts#L754)
e adiciona o dado no dataLayer. Neste mesmo arquivo, também contem 2
componentes, que recebe uma propriedade `event` do tipo AnalyticsEvent e envia o
evento para o dataLayer. O **SendEventOnLoad** dispara o evento quando ocorrer o
evento de `load` do navegador, ele é útil para enviar os eventos, cujo nome tem
padrão `view_*`. Já o **SendEventOnClick** dispara o evento quando o elemento
for clicado.
Exemplos:
1. Enviando evento de `add_to_cart` quando o usuário clicar no botão de
adicionar produto ao Carrinho. Este componente deve ser utilizado dentro de
uma Island.
```tsx
import { sendEvent } from "$store/sdk/analytics.tsx";
interface Props {
name: string;
sku: string;
id: string;
price: number;
discount?: number;
currency: string;
}
function AddToCart({ name, sku, id, price, discount, currency }: Props) {
const handleClick = () => {
addSkuToCart({ sku, quantity: 1 }); // function that call api to add sku
sendEvent({
name: "add_to_cart",
params: {
currency,
value: price,
items: [{
item_id: id,
quantity: 1,
price: price + (discount ?? 0),
discout,
name,
}],
},
});
};
return ;
}
```
2. Enviando evento de `view_item` na página de produto ao carregar a página,
utilizando SendEventOnLoad.
```tsx
import type { Product } from "apps/commerce/types.ts";
import { mapProductToAnalyticsItem } from "apps/commerce/utils/productToAnalyticsItem.ts";
import { SendEventOnLoad } from "$store/sdk/analytics.tsx";
import { useOffer } from "$store/sdk/useOffer.ts";
interface Props {
product: Product;
currency: string;
}
function ProductDetails({ product, currency }: Props) {
const { price, listPrice } = useOffer(product.offers);
return (
<>
>
);
}
```
3. Enviando evento de `select_item` ao clicar num link de produto, utilizando
SendEventOnClick. Utilizar o SendEventOnClick é útil quando o componente é
renderizado no servidor.
```tsx
import type { Product } from "apps/commerce/types.ts";
import { mapProductToAnalyticsItem } from "apps/commerce/utils/productToAnalyticsItem.ts";
import { SendEventOnClick } from "$store/sdk/analytics.tsx";
import { useOffer } from "$store/sdk/useOffer.ts";
interface Props {
product: Product;
itemListId?: string;
itemListName?: string;
}
function ProductCard({ product, itemListName, itemListId }: Props) {
const { price, listPrice } = useOffer(product.offers);
return (
<>
{product.name}
>
);
}
```
## Customizando função de sendEvents
É possível extender a função `sendEvents` para disparar eventos para outras
camadas de dados diferente do `dataLayer`. No arquivo `sdk/analytics.tsx` do seu
projeto deco, você pode customizar a função `sendEvent` adicionando novos
integrações.
Exemplo:
```diff
export const sendEvent = (event: E) => {
if (typeof window.DECO_SITES_STD?.sendAnalyticsEvent !== "function") {
console.info(
"Cannot find Analytics section in your page. Press `.` to add Analytics and supress this warning",
);
return;
}
+
+ if (!window.gtag) {
+ window.gtag = function () {
+ window.dataLayer.push(arguments);
+ };
+ }
+
window.DECO_SITES_STD.sendAnalyticsEvent(event);
+ window.gtag("event", event.name, event.params)
};
```
## Integrando dado do carrinho com o tipo AnalyticsItem
Para integrar um novo modelo de dados de carrinho, adicione um mapeador de dados
no hook de `useCart.ts` da plataforma que está implementando. Exemplo do
[VTEX useCart](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/vtex/hooks/useCart.ts#L1).
# null
Source: https://docs.deco.cx/pt/developing-capabilities/apps/ab-test
Como criar um Teste A/B e acompanhar os resultados?
# Como criar um Teste A/B e acompanhar os resultados?
Os testes A/B para websites consistem em dividir e direcionar o publico para
duas versões diferentes do site e ver em qual delas o engajamento é maior.
Vamos conhecer cada uma das etapas:
* Criando um experimento
* Segmentação do tráfego
* Editando sua variante
* Criação de eventos e coleta de dados
* Funil e resultado
## Criando um experimento
No menu lateral, clique em Experiments

Essa tela lista os seus experimentos, clique em "Create new Experiment"
Alguns dados serão necessários:
* Name
* Description
* Traffic (porcentagem que irá para versão nova)
## Segmentação do tráfego
Você acabou escolher a porcentagem do tráfego para o seu teste, mas pode
personalizar isso ainda mais.
A criação do Experimento, gerou um novo Segmento, que pode ser conferido na aba
lateral, em Segments:

Assim, você também pode combinar segmentos para fazer Testes para públicos
específicos:
Selecione o Teste criado e faça as alterações que deseja.
Exemplos de segmentação:
* **50%** do tráfego **Mobile**
* **30%** do tráfego da **Campanha do Facebook**
* **10%** do tráfego do **Rio de Janeiro**
## Editando sua variante
Agora com o segmento criado, você pode escolher se deseja fazer o teste para uma
página completa ou uma section específica.
Crie uma variante:

Selecione o segmento:

Faça as alterações que deseja:

## Criação de eventos e coleta de dados
Os templates já iniciam com alguns eventos, mas você pode criar novos eventos.
Veja como criar pelo código ou pelo painel:
Exemplo no código:
```javascript
import { sendEvent } from "./sdk/analytics.tsx";
;
```
## Funil e resultado
Além disso, é possível conferir os resultados do Teste A/B
Na tela que lista os Experimentos, selecione o Teste desejado.
Confira os recursos:
### Tamanho da amostra
Indicação de tamanho mínimo da amostra para que o teste seja considerado
estatisticamente relevante.
### Probabilidade
Veja a probabilidade da sua variação ser a vencedora em relação a outra.
### Configuração de metas
Selecione as metas que deseja comparar, não existe nenhum limite.
### Filtro por período
Filtre por período para entender se houve pontos fora da curva durante o teste.
### Funil
Veja a taxa de conversão de cada uma das suas métricas para entender onde está
perdendo o seu usuário.
### Tempo real
Os dados são transferidos em tempo real, chega de esperar um ou dois dias para
analisá-los.


## Setup do GA4 para Teste A/B
Para assegurar a consistência dos dados fornecidos fornecidos ao navegar em um
Teste A/B na deco.cx, utilizamos um cookie, chamado *deco\_segment*.
Esse cookie dura por padrão 30 dias e pode ser utilizado para entender em qual
versão o usuário está.
Todos os dados que vão para o Analytics da deco.cx, já são separados por
segmento.
Porém, para que isso também aconteça no GA4, é necessário verificar esse cookie
e segmentar os eventos com base nessa informação.
* Exemplo de cookie
```
deco_segment=TdCJTIyYWN0aXZlJTIyJTNBJTVCJTVEJTJDJTIyaW5hY3RpdmVEcmF3biUyMiUzQSU1QiUyMlRlc3RlJTIwVGF2YW5vJTIyJTVEJTdE
```
* Para extrair o dado legível deste hash, utilize a função:
```javascript
getData(myCookie) {
return JSON.parse(decodeURIComponent(atob(myCookie)))
}
```
* Isso irá devolver um objeto como:
```json
{
"active": [],
"inactiveDrawn": ["Teste Tavano"]
}
```
Dessa forma, no GTM, você consegue identificar se o usuário está participando do
Teste X, permitindo o envio de eventos de forma segmentada e precisa.
# null
Source: https://docs.deco.cx/pt/developing-capabilities/apps/creating-an-app
Desenvolvendo um App
# Pré-requisitos
Antes de começar, verifique se você possui os seguintes itens instalados no seu
sistema:
* [Deno](https://deno.land/)
## Passo 1: Inicializando o App deco
Para iniciar o desenvolvimento do seu App deco, execute o seguinte comando no
seu terminal:
```bash
deno run -A -r https://deco.cx/start
```
Este comando inicializará um novo projeto de App deco no diretório atual.
Escolha um nome significativo para o seu app quando solicitado.
## Passo 2: Navegando até o Diretório do App deco
Após a inicialização ser concluída, navegue até o diretório do seu App deco
usando o seguinte comando:
```bash
cd $NOME_DO_SEU_APP
```
Substitua `$NOME_DO_SEU_APP` pelo nome que você escolheu para o seu App deco
durante a inicialização.
## Passo 3: Entendendo o Arquivo `mod.ts`
Agora, vamos dar uma olhada no arquivo `mod.ts` do seu App deco:
```ts
import manifest from "./manifest.gen.ts";
import type { Manifest } from "./manifest.gen.ts";
import type { App, AppContext as AC } from "deco/mod.ts";
export interface State {
url: string;
}
export type MyApp = App;
export default function App(
state: State,
): MyApp {
return {
manifest,
state,
};
}
export type AppContext = AC;
```
O arquivo `mod.ts` é o coração do seu App deco e é escrito pelo desenvolvedor.
Neste arquivo, você importa o `manifest` gerado automaticamente e define a
interface `State`, que representa as propriedades do seu app. Pode ser usado
para configurar API keys para uma chamada a alguma dada API.
A função `App` é exportada e recebe o objeto `state` como argumento,
representando o estado do seu app. Em seguida, ela retorna um objeto contendo o
`manifest` e o `state` definidos. Essa função é fundamental para que o seu app
funcione corretamente.
Por fim, é exportado o tipo `AppContext`, que representa o contexto do seu app e
permite acessar as propriedades definidas no `mod.ts`.
## Passo 4: Desenvolvendo o seu App deco
Agora que você entende a estrutura básica do seu App deco, você pode começar a
desenvolvê-lo. Sinta-se à vontade para adicionar mais componentes, como seções,
ações, fluxos de trabalho ou manipuladores, para aprimorar a funcionalidade do
seu app.
## Passo 5: Construindo o seu App deco
Para ver o seu App deco em ação, execute o seguinte comando:
```bash
deno task start
```
Este comando iniciará o seu app e automaticamente gerará os arquivos necessários
para torná-lo utilizável em qualquer site deco.
## Conclusão
Parabéns! Você criou e desenvolveu com sucesso o seu próprio App deco. Você
aprendeu sobre o arquivo `mod.ts`, o coração do seu app, que permite que você
defina o `manifest` e o `state` do seu app. Os Apps deco oferecem uma maneira
poderosa de agrupar e compartilhar capacidades empresariais, tornando mais fácil
a manutenção e escalabilidade dos seus projetos deco. Divirta-se codificando e
sinta-se à vontade para explorar mais recursos do deco para aprimorar ainda mais
os seus apps! 🚀
## Leitura Adicional
* [Tornando um App Instalável](https://deco.cx/docs/en/developing-capabilities/apps/making-an-app-installable)
# null
Source: https://docs.deco.cx/pt/developing-capabilities/apps/making-an-app-installable
Tornando um app Instalável
Para tornar o seu App deco instalável em um site deco, siga estes simples
passos:
1. Execute o seguinte comando em seu terminal para instalar o seu App:
```bash
deno task install $NOME_DO_SEU_APP
```
Substitua `$NOME_DO_SEU_APP` pela localização da sua App, que pode ser uma pasta
no seu sistema de arquivos ou uma URL http do github ou denopkg/denoland.
2. Em seguida, execute o comando a seguir para atualizar o esquema e o manifesto
do seu App:
```bash
deno task start
```
Após concluir essas etapas, o seu App deco estará instalado e pronto para ser
usado em qualquer site deco que você desejar. Agora você pode compartilhar e
aproveitar suas capacidades empresariais de forma prática e eficiente.
Divirta-se construindo e usando os seus Apps deco! 🚀
# null
Source: https://docs.deco.cx/pt/developing-capabilities/blocks/exporting-default-props
Exportando Propriedades Padrão em um Bloco
# Resumo
1. Visão Geral
2. Cenário Atual
3. Exportando Propriedades Padrão nos Parâmetros da Função
4. Implementação
5. Conclusão
# Visão Geral
Este documento detalha o comportamento atual dos valores padrão nos componentes
dentro do Admin e apresenta um novo recurso que permite aos desenvolvedores
especificar propriedades padrão diretamente nos parâmetros da função. Esta
melhoria melhora a experiência do usuário garantindo que os valores padrão sejam
refletidos corretamente tanto na interface do Admin quanto nos componentes
renderizados.
# Cenário Atual
Na configuração atual, os valores padrão para props são codificados diretamente
no código do componente. Isso leva a uma inconsistência entre a interface do
Admin e o componente renderizado:
1. **Admin:** Quando um componente tem valores padrão definidos em seu código, o
formulário na interface do Admin exibe campos vazios em vez desses valores
padrão.
2. **Componente Renderizado:** Apesar dos campos de formulário vazios, o
componente ainda é renderizado com os valores padrão codificados.
3. **JSON:** O arquivo JSON exibido para o desenvolvedor na interface do Admin
não inclui esses valores padrão, o que leva a confusão e uma experiência de
usuário ruim.
## Exemplo
Considere o seguinte cenário: Um componente de rodapé tem props padrão definidas
em seu código. Na interface do Admin, os campos de formulário para essas props
estão vazios, mas o componente é renderizado com os valores codificados. Essa
desconexão torna difícil para os desenvolvedores e gerentes de conteúdo mapear o
texto de entrada para os dados da página com precisão.
```tsx
import { ImageWidget } from "apps/admin/widgets.ts";
import Image from "apps/website/components/Image.tsx";
interface Props {
href?: string;
image?: ImageWidget;
alt?: string;
width?: number;
height?: number;
text?: string;
list?: {
listItem: string;
listItemArray: string[];
};
}
export default function Footer(
{ image, href, text, alt, height, width, list }: Props,
) {
const defaultImage =
"https://ozksgdmyrqcxcwhnbepg.supabase.co/storage/v1/object/public/assets/4959/d7aa9290-074f-417c-99c3-5b0587c8c2ee";
const defaultHref = "https://deco.cx/";
const defaultText = "Made with";
const defaultAlt = "Made with deco.cx";
const defaultHeight = 20;
const defaultWidth = 50;
const defaultList = {
listItem: "1",
listItemArray: ["1", "2"],
};
return (
);
}
```
# Exportando Propriedades Padrão nos Parâmetros da Função
Para resolver este problema, o Admin agora suporta a especificação de
propriedades padrão diretamente nos parâmetros da função de qualquer bloco. Isso
garante que os valores padrão sejam refletidos de forma consistente na
interface, no componente renderizado e no arquivo JSON mostrado aos
desenvolvedores, proporcionando benefícios como:
* **Consistência:** Os valores padrão são visíveis e editáveis na interface do
admin, garantindo uma experiência de usuário consistente.
* **Clareza:** Os desenvolvedores podem ver os valores padrão reais no arquivo
JSON, reduzindo a confusão.
* **Simplicidade:** Mais fácil de gerenciar e atualizar os valores padrão
diretamente nos parâmetros da função.
Este recurso suporta cenários mais simples, cobrindo tipos de dados básicos e
objetos aninhados.
# Implementação
Para especificar propriedades padrão em seu componente, inclua-os diretamente no
parâmetro da função. Abaixo está um exemplo de como fazer isso:
```tsx
import { ImageWidget } from "apps/admin/widgets.ts";
import Image from "apps/website/components/Image.tsx";
interface Props {
href?: string;
image?: ImageWidget;
alt?: string;
width?: number;
height?: number;
text?: string;
list?: {
listItem: string;
listItemArray: string[];
};
}
export default function Footer(
{ image, href, text, alt, height, width, list }: Props = {
image:
"https://ozksgdmyrqcxcwhnbepg.supabase.co/storage/v1/object/public/assets/4959/d7aa9290-074f-417c-99c3-5b0587c8c2ee",
href: "https://deco.cx/",
text: "Made with",
alt: "Made with deco.cx",
height: 20,
width: 50,
list: {
listItem: "1",
listItemArray: ["1", "2"],
},
},
) {
return (
);
}
```
## Explicação
1. **Valores Padrão de Props:** Os valores padrão para image, href, text, alt,
height, width e list são especificados diretamente no parâmetro da função.
2. **Interface de Props:** A interface Props define a estrutura e os tipos das
props.
3. **Lógica do Componente:** A lógica do componente usa esses valores padrão,
garantindo que sejam aplicados de forma consistente.
Então as propriedades definidas no Admin, o preview, o código e o JSON da
section deverá parecer como a imagem a seguir, em vez de aparecer com valores
vazios:

# Conclusão
Ao especificar propriedades padrão diretamente nos parâmetros da função, este
novo recurso melhora a integração entre a interface do admin e a renderização do
componente. Essa mudança simplifica o fluxo de trabalho para os desenvolvedores
e aprimora a experiência do usuário, garantindo que os valores padrão sejam
visíveis e gerenciáveis em todas as partes do Admin.
# null
Source: https://docs.deco.cx/pt/developing-capabilities/deco-records
Deco records é um banco de dados sqlite, pronto para produção de fácil instalação, que está localizado próximo do usuário.
## Instalando o deco records no seu site
> Para iniciar o processo de instalação, crie um ambiente novo, no admin deco do
> seu site, ou resete o ambiente que esteja utilizando, por que será feito um
> publish ao fim desta etapa.
Siga o passo a passo abaixo para realizar a instalação no seu site ou siga o
vídeo.
1. Entre no admin do seu site na deco
2. Na barra lateral clique no menu records
3. Em seguida clique em `Setup Deco Records`, aguarde o processo de instalação
da app e criação do banco de dados. Nesta etapa, será criado e editado alguns
arquivos do seu site (deno.json, .gitignore, manifest.gen.ts,
apps/deco/records.ts, drizzle.config.ts, db/schema.ts,
.deco/blocks/deco-records.json)

4. Após a instalação, clique em `Show diff and publish` para publicar a
instalação da sua app e criação do banco de dados.
5. Revise os arquivos alterados, edite a descrição e, por fim, clique em
`Publish now`.
Após o processo de publicação finalizar, ao acessar o menu de records, terá a
visualização do seu banco de dados.

## Criando tabelas
> Será necessário ter os arquivos que foram criados durante a instalação do deco
> records no computador. Caso seja necessário realize um git pull do seu projeto
> remoto.
Siga o passo a passo abaixo para criar novas tabelas no seu banco de dados ou
siga o vídeo. Neste processo será utilizado o
[drizzle-orm](https://orm.drizzle.team/) e
[drizzle-kit](https://orm.drizzle.team/) para criação das tabelas e
gerenciamento delas no seu banco de dados, através de
[schema migrations](https://medium.com/@joelrodrigues/o-que-s%C3%A3o-database-migrations-f817448870a2).
No exemplo a seguir, será criado uma tabela com nome profiles, com as colunas:
`id`, `name` e `email`.
{/* Use span due to a bug in markdown parser deno-gfm */}
1. Edite o arquivo `db/schema.ts` para criar tabelas.
```ts
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const profiles = sqliteTable("profiles", {
id: integer("id").primaryKey({ autoIncrement: true }),
name: text("name").notNull(),
email: text("email"),
});
```
2. Entre no admin do seu site, clique no menu de `Settings`, em
seguida, na seção Database credentials, clique em `Generate now`. Por fim,
clique no icone de copiar as credenciais.
3. Adicione as credenciais, nas variáveis de ambiente do sistema
operacional do seu computador.

4. Execute a deno task `db:setup:deps` no seu terminal para
instalar as dependências necessárias para realizar o schema migration. É
necessário versão do deno maior ou igual a 1.43.0 e utilizar a variável de
ambiente `DENO_FUTURE=1` para habilitar a instalação de módulos npm.
5. Execute a deno task `db:schema:update`, para criar os arquivos
sql responsáveis pela schema migration e aplica-los ao banco de dados. Execute
este comando sempre que realizar uma alteração nas suas tabelas para gerar novas
schema migrations.
```sh
deno task db:setup:deps
```
6. No menu de records do seu site, no admin da deco, terá as
tabelas de `profiles` e `__drizzle__migrations`. A tabela drizzle\_\_migrations é
auto gerada e utilizada pelo drizzle-kit para gerenciar os schema migrations.

> Adicione os arquivos auto gerados em um git commit e realize um push para o
> git remoto.
## Lendo e escrevendo dados
Com a tabela de profiles criada, agora podemos criar uma
[section](https://deco.cx/docs/pt/concepts/section) de gerenciar perfis, onde
lista, remove e cria um perfil.
Crie uma section que será o gerenciador de perfis.
```ts
import { eq } from "drizzle-orm";
import { SectionProps } from "deco/types.ts";
import type { AppContext } from "site/apps/deco/records.ts";
import { profiles } from "site/db/schema.ts";
import { useSection } from "deco/hooks/useSection.ts";
import Icon from "site/components/ui/Icon.tsx";
type ProfileInsert = typeof profiles.$inferInsert;
type ProfilesKeys = keyof ProfileInsert;
type ProfileValue = ProfileInsert[K];
/**
* Checa se `key` é uma chave válida do tipo profile.
*/
const isProfilePropKey = (
key: string,
): key is ProfilesKeys => key in profiles.$inferInsert;
/**
* Checa se `value` é do mesmo tipo de profiles[key]
*/
const isProfilePropType = (
key: ProfilesKeys,
value: unknown,
): value is ProfileValue =>
typeof value === typeof profiles.$inferInsert[key];
interface Props {
mode?: "create" | "delete";
email?: string;
}
export async function loader(
{ mode, email }: Props,
req: Request,
{ invoke }: AppContext,
) {
// Client do ORM drizzle
const drizzle = await invoke.records.loaders.drizzle();
// Se o mode for create e o request possuir body, então cria um profile novo
if (mode === "create" && req.body) {
const newProfile: Partial = {};
const formData = await req.formData();
formData.forEach((value, key) =>
isProfilePropKey(key) &&
isProfilePropType(key, value) &&
(newProfile[key] = value as any)
);
// Insere newProfile no banco de dados.
await drizzle.insert(profiles).values(
newProfile as typeof profiles.$inferInsert,
);
} // Se mode for delete e email for definido e não vazio, então remova todos or perfis com este email.
else if (mode === "delete" && email) {
await drizzle.delete(profiles).where(eq(profiles.email, email));
}
// Seleciona todos os perfils do banco de dados, trazendo somenente email e nome.
const profilesData = await drizzle.select({
email: profiles.email,
name: profiles.name,
}).from(profiles);
return { profiles: profilesData };
}
export default function ManageProfiles(
{ profiles = [] }: SectionProps,
) {
// Url da section, com a propriedade mode = create, será utilizada para submit do form e criação de novo perfil.
const createUrl = useSection({
props: { mode: "create" },
});
return (
<>
Members List
{profiles.map((profile) => {
// Url da section, com a propriedade mode = delete e email do perfil a ser removido, será utilizada para submit do form e remoção do perfil.
const profileDeleteUrl = useSection({
props: { mode: "delete", email: profile.email ?? "" },
});
return (
{profile.name}{profile.email}
);
})}
>
);
}
```
No exemplo anterior, o inline loader que faz utiliza o cliente `drizzle`, que é
fornecido pela app do records, e faz uma consulta no banco de dados, insere e
remove perfis.
## Desenvolvendo localmente
Para desenvolver localmente é necessário ter as credenciais de acesso ao banco
de dados, que pode ser criada no admin do seu site na deco. Após ter adicionado
as variáveis de ambiente fornecidas pelo admin, execute a deno task
`db:pull:prod` para fazer um dump do seu banco de dados e em seguida, inserir no
banco de dados localmente no arquivo `sqlite.db`.
```sh
deno task db:pull:prod
```
Para acessar o banco do deco records durante o desenvolvimento, é necessário ter
as credenciais nas variáveis de ambiente, que podem ser criadas no admin da
deco. Além das credenciais, precisa de uma nova variável de ambiente, chamada
`USE_PRODUCTION_DB` com valor `1`.
### Links referencia
* [drizzle-orm docs](https://orm.drizzle.team/docs/overview)
* [schema migrations](https://medium.com/@joelrodrigues/o-que-s%C3%A3o-database-migrations-f817448870a2)
# null
Source: https://docs.deco.cx/pt/developing-capabilities/interactive-sections/partial
Defira computação do navegador para o servidor
# Fresh Partials: Revolucionando o Desenvolvimento Web com Deno
Partials capacita os desenvolvedores a otimizar as interações na web,
descarregando determinadas tarefas do dispositivo do usuário para os Servidores
Edge da Deco. Essa abordagem inovadora reduz significativamente a quantidade de
JavaScript necessária para executar websites, resultando em tempos de
carregamento de página mais rápidos e melhores taxas de conversão.
## Introdução aos Partials
Partials, inspirados em [htmx](https://htmx.org/docs/), operam interceptando
interações do usuário em elementos de botão, âncora e formulário. Essas
interações são automaticamente transferidas para nosso servidor, onde geram um
novo estado da Interface do Usuário (UI). Esse novo estado fresco é transmitido
como HTML puro de volta para o navegador do usuário. Nosso tempo de execução
substitui e hidrata o novo estado da UI, criando a ilusão de interatividade do
lado do cliente. Na realidade, todo o processo de computação ocorre em
milissegundos em nossos Servidores Edge. Para obter informações mais detalhadas
sobre Partials, consulte a
[documentação](https://github.com/denoland/fresh/issues/1609) do Fresh.
## Simplificando o Desenvolvimento
Embora os Fresh Partials introduzam um novo domínio de otimização de desempenho,
também trazem complexidade adicional ao ciclo de desenvolvimento. Agora, os
desenvolvedores precisam considerar vários modos de renderização, seu impacto
nos tamanhos de pacote e HTML, latências de interação e como navegar
corretamente em páginas parcialmente renderizadas. Para simplificar esse
processo, a Deco integrou os Partials em uma camada de abstração mais alta do
nosso framework, eliminando a necessidade de os desenvolvedores lidarem com
essas complexidades.
## Usando Partials nas Section
Na Deco, todas as [Sections](https://deco.cx/docs/en/concepts/section) são tratadas como
parciais. Isso significa que você pode incorporar facilmente interatividade do
lado do cliente em qualquer Section sem comprometer os tamanhos de pacote ou os
carregamentos iniciais da página. Isso é especialmente benéfico para a criação
de componentes de IU comuns, como seletores de SKU, recursos de rolagem infinita
e abas. Nas Sections a seguir, vamos aprofundar como aproveitar todo o potencial
dos Partials criando um seletor de SKU super-rápido.
## Exemplo: Seletor de SKU
Os seletores de SKU permitem que os compradores explorem diferentes variações de
um produto, cada um com seu conjunto único de preços, imagens e disponibilidade.
Considere o exemplo a seguir:

Como demonstrado, a alteração do SKU selecionado pode resultar em alterações
significativas na página. Uma abordagem direta é criar um sinal para armazenar o
SKU atualmente selecionado e atualizá-lo a cada clique:
```tsx
// sections/ProductDetails.tsx
export default function DetalhesDoProduto ({ skus }) {
const skuSelecionado = useSignal(skus[0]);
return (
Cor:
)
}
```
No entanto, essa implementação tem uma desvantagem. Para habilitar a
interatividade, toda a Section, incluindo todos os dados de SKU e o código do
componente, é enviada para o navegador, resultando em um desempenho reduzido do
site.
> Observação: Se você isolar apenas os botões como ilhas, a seleção de um SKU
> não atualizará seu preço ou imagem, levando a uma IU inconsistente.
Uma abordagem alternativa é transformar os botões em tags de âncora, acionando
um novo carregamento de página a cada seleção de SKU:
```tsx
// sections/ProductDetails.tsx
export default function DetalhesDoProduto ({ skus }) {
return (
)
}
```
Embora essa abordagem ofereça um desempenho ideal, eliminando a necessidade de
ilhas, ela tem um custo em termos de experiência do usuário (UX). A cada seleção
de SKU, a página é recarregada e o usuário é levado de volta ao topo da página.
Para encontrar um equilíbrio entre UX e desempenho, vamos refatorar esse
componente usando Partials.
### Aprimorando UX e Desempenho com Partials
```tsx
// sections/ProductDetails.tsx
import { usePartialSection } from "deco/hooks/usePartialSection.ts";
export default function DetalhesDoProduto ({ skus }) {
return (
Cor:
ul>
)
}
```
A mágica aqui está no gancho `usePartial` combinado com a tag `button`. Este
gancho aceita um parâmetro `href` e aprimora a tag do botão. Quando o usuário
clica no botão, ele desencadeia a navegação do lado do cliente e aplica
atualizações de diferenças de HTML. Essa abordagem elimina a necessidade de
ilhas, aumentando o desempenho, ao mesmo tempo em que mantém a posição de
rolagem para uma experiência do usuário aprimorada.
## Exemplo: Abas
Embora tenhamos explorado como aproveitar os Partials para seletores de SKU, a
navegação por abas apresenta um desafio único. As abas não possuem URLs
canônicos, tornando difícil gerenciar transições de estado. No entanto, o gancho
`usePartial` nos permite substituir as props que uma Section usa para
renderização, simplificando o processo:
```tsx
import { usePartialSection } from "deco/hooks/usePartialSection.ts";
interface Props {
activeIndex: number;
}
const SectionDeAbas = ({ activeIndex }) => {
return (
);
};
```
Neste exemplo, a prop `activeIndex` é substituída a cada chamada de
`usePartialSection`, simplificando o uso de Partials e eliminando a necessidade
de gerenciar URLs e parâmetros de pesquisa em nossas Sections.
# null
Source: https://docs.deco.cx/pt/developing-capabilities/islands/actions
Uma Action na deco.cx é uma função que modifica dados.
Uma **Action** no deco.cx é uma função em typescript que **modifica** dados
dentro da aplicação. As **Action** são acionadas por *interações* específicas do
**usuário** ou **eventos** e são responsáveis por atualizar o estado da
aplicação de acordo. Ao contrário dos **Loaders**, que buscam dados de fontes
externas, as **Action** concentram-se em modificar os dados já presentes na
aplicação. Elas podem realizar operações como **atualização**, **criação** ou
**exclusão** de dados com base na lógica especificada. As **Action**
proporcionam *controle* preciso e flexibilidade sobre a mutação de dados e
integram-se perfeitamente a outros blocos, como os **Loaders**, para permitir um
fluxo contínuo de dados na aplicação.
As **Action**, assim como os **Loaders**, são implementadas como funções em
typescript e estão localizadas na pasta `/actions/` do seu projeto. Elas podem
ser invocadas em resposta a interações do usuário, envios de formulários ou
qualquer outro gatilho definido. Ao encapsular a lógica de mutação de dados nas
**Action**, os desenvolvedores podem gerenciar e rastrear as alterações feitas
no estado da aplicação, proporcionando aos usuários experiências dinâmicas e
interativas.
## Código de exemplo
Esta é a implementação da Action `newsletter/subscribe.ts`:
```tsx
import { AppContext } from "../../mod.ts";
export interface Props {
email: string;
name?: string;
page?: string;
part?: string;
campaign?: string;
}
const action = async (
props: Props,
_req: Request,
ctx: AppContext,
): Promise => {
const { vcsDeprecated } = ctx;
const form = new FormData();
const {
email,
name = "",
part = "newsletter",
page = "_",
campaign = "newsletter:opt-in",
} = props;
form.append("newsletterClientName", name);
form.append("newsletterClientEmail", email);
form.append("newsInternalPage", page);
form.append("newsInternalPart", part);
form.append("newsInternalCampaign", campaign);
await vcsDeprecated["POST /no-cache/Newsletter.aspx"]({}, {
body: form,
});
};
export default action;
```
[Fonte](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/vtex/actions/newsletter/subscribe.ts#L1C1-L37C23)
## Leitura recomendada
* [Buscando dados de API](https://deco.cx/docs/pt/developing-guide/fetching-data)
* [Invocando funções através da API](https://deco.cx/docs/pt/developing-capabilities/islands/fetching-data-client)
# null
Source: https://docs.deco.cx/pt/developing-capabilities/islands/fetching-data-client
Aprenda a invocar funções através da API.
## Leitura sugerida
* [Conceitos básicos: Loader](https://deco.cx/docs/pt/concepts/loader)
* [Conceitos básicos: Action](https://deco.cx/docs/pt/concepts/action)
A Invocação de funções client-side é um recurso poderoso do live.ts que permite
que você obtenha dados diretamente dos seus funções sem enviar JavaScript para o
navegador. Esse recurso garante que sua obtenção de dados seja única em todo o
seu repositório e ajuda a reduzir a latência do lado do cliente.
Para começar a usar a Invocação de funções client-side, siga estes passos:
1. Importe o objeto `invoke` do arquivo `runtime.ts`
2. Agora você pode emitir invocações usando a função `invoke`. Por exemplo, para
buscar dados de uma função, você usaria o seguinte código:
> Não conseguiu achar esse arquivo?
> [Tente este](https://github.com/deco-sites/fashion/blob/main/runtime.ts)
```ts
import { invoke } from "../runtime.ts";
import { useCallback } from "preact/hooks";
export default function MyIsland() {
const fetchData = useCallback(() => {
const data = await invoke["deco-sites/minha-loja"].loaders.myLoader({/* your function input props */});
}, [])
return
{...}
}
```
Aqui, a função `invoke` recebe um objeto com uma propriedade `key` que
especifica o caminho para sua função e uma propriedade `props` que contém suas
props de entrada da função. Quando você chama `invoke`, o live.ts irá invocar
sua função como faz para renderizar seções e retorná-lo para você como um objeto
JavaScript. É possível também chamar funções definidas em um App instalado no
projeto. Por exemplo,
```ts
const dataAppVtex = await invoke.vtex.loaders.vtexLoader({
/* your function input props */
});
```
Você também pode agrupar solicitações passando um objeto com várias chaves, cada
uma representando uma invocação desejada. Por exemplo:
```ts
const { data1, data2 } = await invoke({
data1: invoke.path1({/* your function input props */}),
data2: invoke.path2({/* your function input props */}),
});
```
Com esses passos, agora você pode começar a usar a Invocação de funções
client-side em sua aplicação Live.ts, happy coding!
# null
Source: https://docs.deco.cx/pt/developing-capabilities/loaders
Um Loader na deco.cx é uma função que retorna os dados necessários para um Site.
Um **Loader** em *deco.cx* é uma função Typescript que retorna tipicamente os
dados necessários em uma [Section](https://deco.cx/docs/pt/concepts/section). Essas funções são
executadas antes da renderização de cada página e seu principal objetivo é
**buscar dados de fontes externas**, transformá-los se necessário e
**fornecê-los às Seções do site que precisam.** Os Loaders podem ser usados para
buscar dados de APIs, bancos de dados ou qualquer outra fonte externa. As
implementações locais de Loaders vivem na pasta `/loaders` do seu projeto, porém
é possível [Instalar novas apps](https://deco.cx/docs/pt/getting-started/installing-an-app) que
contém outros loaders.
Além de buscar dados, os Loaders na *deco.cx* **também podem exportar um tipo de
Props Typescript**, o que permite que sejam configurados no
[Admin](https://deco.cx/admin) assim como as
[Sections](https://deco.cx/docs/pt/concepts/section). Isso significa que os usuários de negócio
podem configurar detalhes sobre como o Loader irá operar, como **configurar
filtros** ou **passar parâmetros para APIs.** Ao tornar os Loaders configuráveis
dessa maneira, fica mais fácil gerenciar os dados que fluem para as Sections e
garantir que o Site esteja exibindo as informações corretas para os visitantes.
Outro benefício dos Loaders na *deco.cx* é que **vários loaders podem retornar o
mesmo tipo de dados**. Isso permite que as [Sections](https://deco.cx/docs/pt/concepts/section)
que recebem, por exemplo, um *array* de Produtos canônico obtenham dados de
diferentes Loaders, dependendo da configuração do usuário. Isso significa que as
UIs podem ser reutilizadas em [Sites](https://deco.cx/docs/pt/concepts/site) ou entre times,
facilitando o gerenciamento e a escala do seu projeto.
> Todas as Sections para lojas de *ecommerce* criadas por *deco.cx* na
> [Fashion](https://github.com/deco-sites/fashion) usam um tipo de Produt
> canônico e também cada Loader que se conecta às APIs dos *ecommerce
> providers*. Isso significa que você pode reutilizar a mesma UI para mostrar
> dados de diferentes locais, dependendo da configuração.
## Código de exemplo
Esta é a implementação do Loader `shopify/loaders/ProductList.ts`:
```tsx
import type { Product } from "../../commerce/types.ts";
import { AppContext } from "../../shopify/mod.ts";
import { ListProducts } from "../utils/storefront/queries.ts";
import {
ListProductsQuery,
ListProductsQueryVariables,
} from "../utils/storefront/storefront.graphql.gen.ts";
import { toProduct } from "../utils/transform.ts";
export interface Props {
/** @description search term to use on search */
query: string;
/** @description total number of items to display */
count: number;
}
/**
* @title Shopify Integration
* @description Product List loader
*/
const loader = async (
props: Props,
_req: Request,
ctx: AppContext,
): Promise => {
const { storefront } = ctx;
const count = props.count ?? 12;
const query = props.query || "";
const data = await storefront.query<
ListProductsQuery,
ListProductsQueryVariables
>({
variables: { first: count, query },
...ListProducts,
});
// Transform Shopify product format into schema.org's compatible format
// If a property is missing from the final `products` array you can add
// it in here
const products = data?.products.nodes.map((p) =>
toProduct(p, p.variants.nodes[0], new URL(_req.url))
);
return products ?? [];
};
export default loader;
```
[Fonte](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/shopify/loaders/ProductList.ts#L1)
## Leitura recomendada
* [Buscando dados de API](https://deco.cx/docs/pt/develping/fetching-data)
* [Invocando um loader através da API](https://deco.cx/docs/pt/developing-capabilities/islands/fetching-data-client)
# null
Source: https://docs.deco.cx/pt/developing-capabilities/manage-block-access
# Gerenciando Acesso de Loaders/Actions
Por padrão, todos os loaders e actions no deco.cx são publicamente acessíveis. No entanto, você pode precisar restringir o acesso a certos loaders/actions que lidam com operações sensíveis ou APIs privadas. Este guia explica como controlar a visibilidade de loaders/actions.
## Opções de Visibilidade
Existem dois níveis de visibilidade disponíveis:
* `private`: Pode ser invocado apenas no lado do servidor através do `ctx.invoke`
* `public`: Pode ser chamado tanto do servidor quanto do cliente através de:
* Chamadas `invoke` em tempo de execução
* Acesso direto via path `/live/invoke/{path/to/block.ts}`
## Definindo Visibilidade Padrão
Para definir o nível de visibilidade de um loader/action, exporte uma variável `defaultVisibility`:
```typescript
// Torna o loader publicamente acessível
export const defaultVisibility = 'public'
// Torna o loader privado (apenas lado do servidor)
export const defaultVisibility = 'private'
```
## Sobrescrevendo Visibilidade
Você pode sobrescrever as configurações de visibilidade padrão no seu arquivo `fresh.config.ts` usando a opção `visibilityOverrides`:
```typescript
import { defineConfig } from "$fresh/server.ts";
import { plugins } from "deco/plugins/deco.ts";
import manifest from "./manifest.gen.ts";
export default defineConfig({
plugins: plugins({
manifest,
htmx: true,
visibilityOverrides: {
"site/loaders/minicart.ts": "public",
"vtex/loaders/cart.ts": "private"
},
}),
});
```
## Boas Práticas de Segurança
Ao decidir os níveis de visibilidade:
### Use `private` para
* Acessar APIs privadas/internas
* Operações envolvendo credenciais ou segredos
* Processamento de dados sensíveis de usuários/negócios
* Integrações backend que requerem autenticação
### Use `public` para
* Leitura de dados públicos de produtos
* Busca de conteúdo público
* Carregamento de dados no lado do cliente
* Operações voltadas ao usuário que não expõem dados sensíveis
## Documentação Relacionada
* [Buscando Dados](/docs/pt/developing-guide/fetching-data)
* [Carregamento de Dados no Cliente](/docs/pt/developing-capabilities/islands/fetching-data-client)
* [Conceitos Principais: Loaders](/docs/pt/concepts/loader)
# null
Source: https://docs.deco.cx/pt/developing-capabilities/modifying-status
Modificando o status de retorno de uma pagina
## Visão Geral
A modificação do status de retorno permite que você informe ao navegador de
forma correta qual o retorno que esta sendo enviado na pagina com base em
qualquer criterio desejado. Isso garante uma melhor indexação por mecanismos de
pesquisa uma vez que, por exemplo, uma pagina não encontrada com status correto
não será indexada por eles.
## Implementação
Para modificar o status de retorno de uma pagina a partir de uma seção, siga
estes passos simples:
1. Crie um carregador inline dentro do componente da sua seção.
```tsx
export default function MyComponent(props: Props) {
// Sua lógica de componente vai aqui
// ...
}
export const loader = (props: Props, req: Request, ctx: AppContext) => {
// Sua condição para a modificação de status
if (SUA_CONDICAO_PARA_MODIFICAR_O_STATUS) {
ctx.response.status = STATUS_DESEJADO;
}
// Retorne as props do componente
return props;
};
```
2. Dentro da função `loader`, defina a condição que determina se o status deve
ser modificado. Se a condição for atendida, atribua o status desejado a
resposta contida no contexto.
## Exemplo
Digamos que você deseje que se sua busca não retornou nenhum elemento o retorno
da pagina seja `404 (Not Found)`:
```tsx
export default function MyComponent(props: Props) {
// Sua lógica de componente vai aqui
// ...
}
export const loader = (props: Props, req: Request, ctx: AppContext) => {
// Verifique se não há nenhum elemento
if (!props.items || !props.items.length) {
ctx.response.status = 404;
}
// Retorne as props do componente
return props;
};
```
Neste exemplo, se a propriedade `items` não existir ou não conter nenhum
elemento a seção modificará o status de retorno de toda a pagina para `404`
## Lembre-se
* A seção modificará o status de toda pagina em que estiver sendo chamada e que
a condição for satisfeita.
* Use os codigos de status correto para cada situação para seu SEO não ser
afetado negativamente.
# null
Source: https://docs.deco.cx/pt/developing-capabilities/section-properties/annotations
Customize o comportamento do formulário do Admin da Deco com annotations nas suas propriedades.
Customize o comportamento do formulário do
[Admin da Deco](https://admin.deco.cx) com annotations nas suas propriedades.
Ao usar tipos nativos (number, string, etc.), o editor usará o nome da
propriedade como a *label* padrão do formulário. Mas é possível personalizar
isso usando tags [JSDoc](https://jsdoc.app/).
* Exemplo:
```tsx
export interface Props {
/** @title Numero de produtos */
/** @description Total de produtos para mostrar na vitrine */
count: number;
}
```
* Editor:
Lista com todas as annotations suportadas:
| Annotation | Descrição | Uso |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `@title` | Recebe texto que será usado como título da label daquele input no formulário. | `@title Número de produtos` |
| `@description` | Recebe texto que será usado como descrição na label daquele input no formulário. | `@description Total de produtos para mostrar na vitrine` |
| `@format` | Configura um campo para ser formatado de forma diferente. Isso pode fazer com que seu [Widget](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets) mude. | `@format [Format value](#valores-possíveis-para-o-format)` |
| `@hide` | Esconde essa propriedade no formulário do Admin. O valor continua presente no JSON da Section. | `@hide true` |
| `@ignore` | O valor e a propriedade são completamente ignorados. | `@ignore` |
| `@maximum` | Configura um valor máximo para aquele campo. Funciona em propriedades do tipo `number`. (valor \<= X) | `@maximum 10` |
| `@minimum` | Configura um valor mínimo para aquele campo. Funciona em propriedades do tipo `number`. (valor >= X) | `@minimum 15` |
| `@exclusiveMaximum` | Configura um valor máximo para aquele campo. Funciona em propriedades do tipo `number`. É a contraparte exclusiva do `@maximum`. (valor \< X) | `@exclusiveMaximum 10` |
| `@exclusiveMinimum` | Configura um valor mínimo para aquele campo. Funciona em propriedades do tipo `number`. É a contraparte exclusiva do `@minimum`. (valor > X) | `@exclusiveMinimum 15` |
| `@maxLength` | Configura um tamanho máximo para o texto de um campo. Funciona em propriedades do tipo `string`. | `@maxLength 30` |
| `@minLength` | Configura um tamanho mínimo para o texto de um campo. Funciona em propriedades do tipo `string`. | `@minLength 8` |
| `@readOnly` | Faz com que um campo não possa ser editado no formulário de admin, mas possa ser lido. | `@readOnly` |
| `@uniqueItems` | Faz com que campos do tipo `array` não possam ter valores duplicados. | `@uniqueItems true` |
| `@maxItems` | Faz com que campos do tipo `array` não possam ter mais que X valores. | `@maxItems 3` |
| `@minItems` | Faz com que campos do tipo `array` não possam ter menos que X valores. | `@minItems 2` |
| `@default` | Configura um valor padrão para aquele campo. Funciona somente com tipos primitivos. | `@default Testando` |
| `@deprecated` | Marca um campo como descontinuado. | `@deprecated vamos remover esse campo na próxima atualização` |
| `@options` | É necessário para o funcionamento das widgets [dynamic options](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets#dynamic-options), [button group](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets#button-group) e [icon select](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets#icon-select). | `@options deco-sites/minhaloja/loaders/produtos.ts` |
| `@language` | Usado em conjunto com `@format code`, para definir a linguagem do editor. | `@language javascript` |
| `@aiContext` | Usado para definir o contexto do campo, melhorando as sugestões por Inteligência Artifical. | `@aiContext Sugira um título chamativo para uma prateleira, relacionado ao mundo Fashion` |
## Valores possíveis para o @format
* `@format color`: Renderiza um input de cor no lugar de um de texto.
* `@format date`: Renderiza um input de data no lugar de um de texto.
* `@format html`: Renderiza um input que abre um Editor WYSIWYG para edição
avançada do texto por html.
* `@format dynamic-options`:
[Ler sobre aqui](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets#dynamic-options).
# Templates em annotations com Mustache
Nossas annotations também suportam templating, através do
[Mustache](https://mustache.github.io/).
Para utilizá-las, é bem simples:
```ts
/**
* @title {{{nome}}}
*/
interface Pessoa {
nome: string;
}
export interface Props {
pessoas: Pessoa[];
}
```
Resultado no Admin:
# null
Source: https://docs.deco.cx/pt/developing-capabilities/section-properties/standard-data-types
Aprenda como criar componentes universais para que possam ser usados em qualquer lugar
Componentes universais são componentes que não dependente de uma *fonte*
específica de dado para determinar seu comportamento. A única coisa que lhes
importa é o `formato` do dado, isso geralmente acontece quando o componente é
feito para ser usado em vários lugares diferentes (inclusive há possibilidade
entre usa-lo entre sites distintos) sem que seja necessário ler de alguma API
específica, ou seja, sem nenhuma dependência externa (a.k.a implicit
dependency).
Um exemplo de um componente universal é a
[ProductShelf da loja Fashion](https://github.com/deco-sites/fashion/blob/main/components/product/ProductShelf.tsx#L15),
vamos dar uma olhada nele;
```tsx
export interface Props {
title: string;
products: Product[] | null;
itemsPerPage?: number;
}
function ProductShelf({
title,
products,
}: Props) {
// ...implementation
}
```
Perceba que, apesar da ProductShelf depender de uma lista de "Product" pra
funcionar, ela não depende de qual é a fonte do dado que vai prover essa
informação. Isso só é possível porque o tipo `Product` é um tipo criado por uma
entidade central no `schema.org`. Uma outra forma possível de pensar nossa
ProductShelf seria escrever um
[Inline Loader](https://deco.cx/docs/pt/developing-guide/fetching-data) e fazer com que esse
inline loader leia os dados da API de um e-commerce em específico (e.g Shopify)
e só então renderizar a ProductShelf.
Isso é totalmente possível e factível, no entanto, deve-se atentar que quando
isso é feito, o nosso usuário de negócio perde a possibilidade de, por exemplo,
trocar a fonte de dados de Shopify para VTEX, o que é uma feature bastante
poderosa para evitar lock-in em uma plataforma especifica. Nesse sentido, um
component universal faz com que as dependencias nos tipo sejam invertidas, ao
invés do componente depender da API, na verdade o componente depende apenas do
`formato` do dado e permite com que `loaders` sejam implementados de forma a
retornarem esse tipo em comum, fazendo com que seja possível escolher o dado
loader ao configurar as propriedades do componente no Editor Admin.
De fato, nossa ProductShelf possui ao menos quatro implementações distintas para
ler produtos de APIs e até mesmo plataformas de e-commerce distintas, são elas:
[VNDAProductList](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/vnda/loaders/productList.ts#L1),
[VTEXProductList](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/vtex/loaders/intelligentSearch/productList.ts#L1),
[VTEXLegacyProductList](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/vtex/loaders/legacy/productList.ts#L1),
It is
[ShopifyProductList](https://github.com/deco-cx/apps/blob/3e337b6b2996d7ecd72db34174896638c92f8811/shopify/loaders/ProductList.ts#L1)
Isso faz com que Universal Components sejam algo que tem um valor e usabilidade
muito grande comparado a componentes que dependem de dados de APIs!
## Leitura sugerida
Componentes universais faz com que a interoperabilidade entre plataformas seja
possível e o mais fácil possível. Leia mais sobre como criar loaders abaixo nos
nossos tutoriais;
* [Carregando dados de uma API](https://deco.cx/docs/pt/developing-guide/fetching-data)
* [Conceitos básicos: Loaders](https://deco.cx/docs/pt/concepts/loader)
# null
Source: https://docs.deco.cx/pt/developing-capabilities/section-properties/using-secrets
Utilizando Secrets em Sites Deco
# Utilizando Secrets em Sites Deco
secrets são uma funcionalidade poderosa em sites deco que permitem armazenar
informações sensíveis com segurança, como chaves de API ou senhas. Ao utilizar
secrets, você pode gerenciar e proteger facilmente os dados confidenciais do seu
site.
## Pré-requisitos
Antes de começar, verifique se você possui o seguinte:
* Um projeto de site deco configurado.
* Compreensão sobre props e loaders no deco.
## Passo 1: Declarando um Prop de secret
Para usar secrets no seu site, você precisa declarar um prop de secret nos seus
componentes. Aqui está um exemplo de como fazer isso em uma seção usando um
inline loader:
```tsx
import { Secret } from "apps/website/loaders/secret.ts";
export interface Props {
secret: Secret;
}
export const loader = async (props: Props) => {
const secretValue = props?.secret?.get();
// Use o secret aqui
};
```
Neste exemplo, o prop `secret` é declarado na interface `Props`. A função
`loader` recupera o valor do secret usando o método `get()` e, em seguida, você
pode usar o secret no seu código.
## Passo 2: Configurando secrets
Após declarar o prop de secret, os usuários podem configurar secrets para o seu
site. No entanto, observe que a configuração de secrets apontando para
`localhost` não funcionará. Você deve apontar para o domínio de produção, o que
significa que você precisa de pelo menos um deployment declarando a dependência
do secret.
> Importante: Uma vez que o Secret for configurado, o valor original dele não é
> revelado na UI do Admin, ou seja, você precisa ter acesso ao segredo para
> saber o valor original dele.
## Passo 3: Lidando com o Desenvolvimento Local
Ao desenvolver localmente, um secret tem um "nome" na interface do admin. Esse
nome pode ser preenchido como uma variável de ambiente, que será usada
localmente em vez da chave real usada em produção.
Importante: Você pode setar uma variável de ambiente passando o valor dela antes
de rodar o commando final, por exemplo:
```sh
ENV_VAR=mysecretvalue deno task start
```
Isto fará com que o valor de `ENV_VAR` (que deve ser o nome da sua secret) seja
`mysecretvalue` quando usada localmente.
# null
Source: https://docs.deco.cx/pt/developing-capabilities/section-properties/utility-types
Sections podem ser codificadas por desenvolvedores e configuradas por usuários de negócio no Admin. Aprenda todas as suas capacidades.
## Leitura sugerida
* [Conceitos: Section](https://deco.cx/docs/pt/concepts/section)
* [Codificando uma nova Section](https://deco.cx/docs/pt/developing-guide/hello-world)
Você já sabe que é fácil criar uma [Section](https://deco.cx/docs/pt/concepts/section)
configurável na *deco.cx*. Neste post vamos detalhar todas as formas possíveis
de declarar os types das `props` e como isso afeta o formulário que renderizamos
no Admin da *deco.cx*.
## Personalizando Sections
As Sections, como componentes [Preact](https://preactjs.org), aceitam `props`
como seus primeiro argumento e usam esses valores em seus *markups* para exibir
textos, imagens ou configurar algum comportamento.
Normalmente, essas `props` são passadas a partir de outro componente, mas quando
você usa *deco.cx* **essas props são configuradas no Admin**, o que facilita
usuários de negócios alterarem o conteúdo em seus Sites.
Para declarar como essas `props` serão configuradas você usa o **Typescript
type**, especificando quais props e seus respectivos tipos como `string`,
`number`, `Array`, etc.
*Exemplo:*
* Configuração de Section em um site *deco.cx*.
```tsx
interface Props {
título: string;
}
export default function LatestPosts({ title }: Props) {
return (
{title}
Esta é uma Section de exemplo
);
}
```
* Como fica o editor no Admin:
## Tipos suportados
O editor aceita um subconjunto de tipos Typescript para configuração da Section.
Esta é a lista de tipos suportados atualmente:
### Tipos nativos
#### string
```ts
export interface Props {
title: string;
}
```
#### number
```ts
export interface Props {
lineNumber: número;
}
```
#### object
```ts
export interface Props {
address: {
street: string;
postalCode: string;
};
}
```
#### array
```ts
export default {
menuItems: Array<{ label: string; value: string }>;
}
```
#### string options
```ts
export interface Props {
variant: "primary" | "secondary" | "tertiary";
}
```
### Tipos Especiais
#### Imagem
Este tipo renderiza um *widget* de upload de imagem no editor, possibilitando os
usuários **fazer upload de imagens**.
O tipo é um *wrapper* para `string`, então a Section receberá a URL da imagem
hospedada nos servidores da *deco.cx*.
**Opcional:** A *deco.cx* fornece um componente que otimiza o carregamento da
imagens e pode ser usado em conjunto com esta propriedade.
Exemplo:
```tsx
import type { ImageWidget as Image } from "apps/admin/widgets.ts";
export interface props {
bannerImg: Image;
}
```
#### Vídeo
Semelhante à Imagem, as propriedades com este tipo serão editadas através de um
*widget* com a possibilidade de upload de vídeos.
[Exemplo de uso aqui](https://github.com/deco-sites/fashion/blob/e15a0320fe9e0b7503eb4723f7c230b23886c2b5/sections/VideoCarousel.tsx#L3).
```ts
import type { VideoWidget as Video } from "apps/admin/widgets.ts";
export interface props {
myVideo: Video;
}
```
### Enriquecendo o editor
Ao usar tipos nativos, o editor usará o nome do prop como a *label* padrão do
formulário. Mas é possível personalizar isso usando tags
[JSDoc](https://jsdoc.app/).
* Exemplo: Código da Section:
```tsx
export interface props {
/** @title Numero de produtos */
/** @description Total de produtos para mostrar na vitrine */
count: number;
}
```
* Editor:
As tags disponíveis são os campos compatíveis com
[JSON Schema](https://json-schema.org/), ou seja, `@title`, `@description`,
`@format` entre outros. Por exemplo, para aceitar apenas e-mails:
```tsx
export interface props {
/** @format email */
color: string;
}
```
Outros tipos de formatos válidos são: `uri`, `color`. Você pode ler mais sobre
isso
[na documentação de Annotations](https://deco.cx/docs/pt/developing-capabilities/section-properties/annotations).
# null
Source: https://docs.deco.cx/pt/developing-capabilities/section-properties/widgets
Lista de widgets disponíveis no Admin da Deco.
Widgets são componentes que aparecem no formulário do
[Admin da Deco](https://admin.deco.cx) de forma correspondente as propriedades
de um [Bloco](https://deco.cx/docs/pt/concepts/block). Aqui está uma lista dos Widgets
existentes:
## TextArea
Este Widget renderiza um campo de texto especial. Basta utilizar o tipo
TextArea. Exemplo:
```ts
import { TextArea } from "apps/admin/widgets.ts";
export interface Props {
context: TextArea;
}
```
## CheckBox
Este widget é renderizado para campos do tipo `boolean`. Exemplo:
```ts
export interface Props {
showTopbar: boolean;
}
```
## ImageUri
Este widget é renderizado para campos do tipo `ImageWidget`. Este tipo pode ser
importado de `deco-cx/apps`. Exemplo:
```ts
import { ImageWidget as Image } from "apps/admin/widgets.ts";
export interface Props {
imagem: Image;
}
```
## VideoUri
Este widget é renderizado para campos do tipo `VideoWidget`. Este tipo pode ser
importado de `deco-cx/apps`. Exemplo:
```ts
import { VideoWidget as Video } from "apps/admin/widgets.ts";
export interface Props {
video: Video;
}
```
## Section
O widget `Section` é utilizado para criar Sections que podem receber outras
Sections como propriedades. Funciona de forma bem similar a receber outros
componentes por props.
Ao utilizar este campo, você pode selecionar qualquer Section do seu projeto. O
formulário renderizado nesta widget toma forma do mesmo formulário que seria
renderizado para a Section que foi selecionada.
Este widget é renderizado para campos do tipo `Section`. Este tipo pode ser
importado de `deco-cx/apps`. Exemplo:
```ts
import { Section } from "deco/blocks/section.ts";
export interface Props {
innerSection: Section;
}
```
## Select
O widget Select é empregado para criar listas suspensas ou menus de opções,
proporcionando aos usuários a capacidade de escolher entre diferentes
alternativas. Esse widget é renderizado para campos cujo tipo é uma
[Union](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types)
do Typescript. Exemplo:
```ts
export interface Props {
layout: "Grid" | "Table" | "List";
}
```
## HTML
O widget HTML é renderizado para campos do tipo `HTMLWidget`. Este widget
permite a edição do conteúdo de seu campo através de um
[Editor WYSIWYG (What You See Is What You Get)](https://tecnoblog.net/responde/o-que-e-um-editor-wysiwyg/).
Este tipo pode ser importado de `deco-cx/apps`. Exemplo:
```ts
import { HTMLWidget as HTML } from "apps/admin/widgets.ts";
export interface Props {
content: HTML;
}
```
## RichText
O widget RichText representa texto formatado com suporte para várias opções de
estilos e formatação. Este widget permite que os desenvolvedores incluam
conteúdo de texto que pode ter diferentes fontes, tamanhos, cores e outros
estilos de formatação aplicados.
```ts
import { RichText } from "apps/admin/widgets.ts";
export interface Props {
content: RichText;
}
```
## Secret
O widget Secret é destinado a campos sensíveis, como senhas, e garante que o
conteúdo seja encriptado para proteger informações confidenciais. Ele é
renderizado para campos do tipo `Secret`. Este tipo pode ser importado de
`deco-cx/apps`. Exemplo:
```ts
import { Secret } from "apps/website/loaders/secret.ts";
export interface Props {
password: Secret;
}
```
## Dynamic Options
Este widget é especialmente útil quando as opções disponíveis em um campo
dependem de dados dinâmicos. Ele exibe em sua interface o mesmo que o
[Select](#select), porém suas opções podem ser carregadas dinamicamente de outra
prop ou via loader!
Exemplo 1:
`MySection.tsx`
```ts
export interface Props {
names: string[];
/**
* @format dynamic-options
* @options {{{names}}}
*/
name: string;
}
```
Exemplo 2:
`MinhaSection.tsx`
```ts
export interface Props {
/**
* @format dynamic-options
* @options deco-sites/minhaloja/loaders/produtos.ts
*/
produto: string;
}
```
`minhaloja/loaders/produtos.ts`
```ts
import { allowCorsFor, FnContext } from "deco/mod.ts";
interface Props {
term?: string;
}
export default function ProductsLoader(
props: Props,
req: Request,
ctx: FnContext,
) {
// Allow Cors
Object.entries(allowCorsFor(req)).map(([name, value]) => {
ctx.response.headers.set(name, value);
});
// fetch X api
const products = ["Product X", "Product Y", "Product Z"];
return products.filter((p) => p.includes(props.term));
}
```
Perceba que o seu loader pode receber um `term`, isso vai se comportar como uma
busca.
## Color Input
O widget Color Input exibe um círculo preenchido representando a cor selecionada
juntamente com seu valor hexadecimal correspondente. Os usuários podem interagir
com o widget clicando nele para abrir um seletor de cores. Valor padrão: "#000".
Exemplo:
`MySection.tsx`
```ts
import { Color } from "apps/admin/widgets.ts";
export interface Props {
"primary"?: Color;
}
```
## Code
O Widget Code exibe um Editor de código.
Utilize os tipos `CSS`, `TypeScript` ou `Json`. Exemplo:
```ts
import { CSS, Json, TypeScript } from "apps/admin/widgets.ts";
export interface Props {
myCSSCode?: CSS;
myTSCode?: TypeScript;
myJsonCode?: Json;
}
```

## Button Group
O widget Button Group permite que você renderize opções de seleção em um formato
de ícone, fornecendo uma maneira visualmente atraente de escolher opções. Cada
opção é representada por um ícone, oferecendo flexibilidade e personalização
para sua aplicação.
Exemplo:
`MySection.tsx`
```ts
export interface Props {
/**
* @format button-group
* @options site/loaders/icons.ts
*/
textAlignment?: "Left" | "Center" | "Right";
}
```
Para garantir que os ícones estejam disponíveis para seleção no widget, é
essencial que cada ícone seja definido explicitamente como uma string SVG em
`static/adminIcons.ts` e exportado como uma constante:
`mystore/static/adminIcons.ts`
```ts
// adminIcons.ts contém todos os ícones disponíveis necessários para renderizar o widget, em um formato de string.
export const AlignLeft =
``;
```
`mystore/loaders/icons.ts`
```ts
import { allowCorsFor, FnContext } from "deco/mod.ts";
// Importe ícones em formato de string
import { AlignCenter, AlignLeft, AlignRight } from "../static/adminIcons.ts";
// Defina ícones com seus labels e props correspondentes conforme definido na sua interface Props
const icons = [
{ component: AlignLeft, label: "Left", prop: "textAlignment" },
{ component: AlignCenter, label: "Center", prop: "textAlignment" },
{ component: AlignRight, label: "Right", prop: "textAlignment" },
];
// Loader para mapear ícones para o formato esperado pelo widget Button Group
export default function IconsLoader(
_props: unknown,
req: Request,
ctx: FnContext,
) {
Object.entries(allowCorsFor(req)).map(([name, value]) => {
ctx.response.headers.set(name, value);
});
const iconsMap = icons.map((icon) => ({
value: icon.component,
label: icon.label,
prop: icon.prop,
}));
return iconsMap;
}
```
## Icon Select
O widget Icon Select permite criar um seletor de entrada para ícones, onde cada
opção consiste em um ícone e sua etiqueta. Isso permite aos usuários visualizar
e escolher facilmente o ícone certo. Todos os ícones renderizados no widget
devem ser definidos explicitamente como strings SVG.
Exemplo:
`MySection.tsx`
```ts
export interface Props {
/**
* @format icon-select
* @options deco-sites/storefront/loaders/availableIcons.ts
*/
icon: AvailableIcons;
}
```
Para garantir que todos os ícones sejam devidamente integrados e selecionáveis
em nosso widget, cada ícone do seu arquivo `static/sprites.svg` deve ser
explicitamente definido como uma string SVG e exportado de um arquivo separado,
`static/adminIcons.ts`. Nós simplificamos esse processo com o script
`generate-icons.ts` no template da loja Deco, que automatiza a conversão dos
ícones de `sprites.svg` para o formato de string e os grava em `adminIcons.ts`.
Para adicionar novos ícones, basta inseri-los no seu `sprites.svg`. Em seguida,
interrompa a execução do projeto e reinicie-o usando `deno task run`. Isso
aciona o script `generate-icons.ts`, atualizando o arquivo `adminIcons.ts` com
os novos ícones, tornando-os imediatamente disponíveis para seleção no widget.
Essa abordagem centraliza as atualizações de ícones em `sprites.svg`, garantindo
um processo de atualização suave.
Esteja ciente de que, se um ícone não foi gerado como uma string em
static/adminIcons.ts, ele não será exibido como uma opção no seletor.
`mystore/loaders/availableIcons.ts`
```ts
import { allowCorsFor, FnContext } from "deco/mod.ts";
import { AvailableIcons } from "../static/adminIcons.ts";
const icons = Object.keys(AvailableIcons).map((iconName) => ({
component: AvailableIcons[iconName as keyof typeof AvailableIcons],
label: iconName,
}));
// Loader para mapear todos os ícones disponíveis que serão usados nos widgets IconSelect.
export default function IconsLoader(
_props: unknown,
req: Request,
ctx: FnContext,
) {
// Permitir Cors
Object.entries(allowCorsFor(req)).map(([name, value]) => {
ctx.response.headers.set(name, value);
});
// Mapeamento de ícones para { value, label, icon }
const iconsMap = icons.map((icon) => ({
icon: icon.component,
label: icon.label,
value: icon.label,
}));
return iconsMap;
}
```
# null
Source: https://docs.deco.cx/pt/developing-capabilities/sections/accept-a-section
Aceitando Outras Seções como Parâmetros em Sua Seção
# Aceitando Outras Seções como Parâmetros em Sua Seção
No deco, você pode criar [Seções](https://deco.cx/docs/pt-br/concepts/section) poderosas e
flexíveis ao aceitar outras seções como parâmetros. Isso permite que você
construa componentes modulares e componíveis que podem ser facilmente
personalizados e reutilizados em diferentes contextos.
## Visão Geral
Ao criar uma Seção que aceita outras seções como parâmetros, você define uma
interface para as props do seu componente de Seção. Essa interface inclui uma
propriedade com o nome da sua escolha, que é do tipo `Section`. O tipo `Section`
é um tipo genérico que representa qualquer outra seção no deco.
## Implementação
Para criar uma Seção que aceita outras Seções como parâmetros, siga estas
etapas:
1. Importe o tipo `Section` de `deco/blocks/section.ts`.
2. Defina uma interface para as props do seu componente de seção. Inclua uma
propriedade com nome de sua escolha, que é do tipo `Section`.
```tsx
// MySection.tsx
import { Section } from "deco/blocks/section.ts";
export interface Props {
myProp: Section;
}
export default function MySection({ myProp: { Component, props } }: Props) {
return (
);
}
```
3. Dentro do seu componente de seção, acesse as propriedades `Component` e
`props` da prop `myProp`. A propriedade `Component` representa a função do
componente da seção passada como parâmetro, e a propriedade `props` contém as
props dessa seção.
## Exemplo
Digamos que você tenha uma seção chamada `ProductCardSection` que renderiza um
cartão de produto com base em algumas props:
```tsx
// ProductCardSection.tsx
export interface Props {
title: string;
price: number;
imageUrl: string;
}
export default function ProductCardSection({ title, price, imageUrl }: Props) {
return (
{title}
{price}
);
}
```
Agora, você deseja criar uma seção de ordem superior chamada
`ProductContainerSection`, que aceita uma `ProductCardSection` como parâmetro e
a envolve em um contêiner:
```tsx
// ProductContainerSection.tsx
import { Section } from "deco/blocks/section.ts";
export interface Props {
myProp: Section;
}
export default function ProductContainerSection(
{ myProp: { Component, props } }: Props,
) {
return (
);
}
```
Com essa configuração, agora você pode usar `ProductContainerSection` para
envolver qualquer outra seção, incluindo `ProductCardSection`, e adicionar um
contêiner ao redor dela.
Agora, suponha que você queira restringir sua seção a `ProductCard` porque tem
muitas seções em seu site, mas apenas essa deve se encaixar nesse local, você
pode fazer o seguinte:
```tsx
// ProductCardSection.tsx
import { JSX } from "preact";
// Defina um tipo nomeado, por exemplo, "ProductCard," apontando para `JSX.Element`
export type ProductCard = JSX.Element;
// Defina a interface de props
export interface Props {
title: string;
price: number;
imageUrl: string;
}
// Implemente a seção e especifique o tipo de retorno como "ProductCard"
export default function ProductCardSection(
{ title, price, imageUrl }: Props,
): ProductCard {
return (
{title}
{price}
);
}
```
Agora, você pode depender diretamente de `ProductCard`:
```tsx
// ProductContainerSection.tsx
import { Section } from "deco/blocks/section.ts";
import { ProductCard } from "./ProductCardSection.tsx";
// Especifique a interface de propriedades com `Section`
export interface Props {
myProp: Section;
}
// Implemente a seção
export default function ProductContainerSection(
{ myProp: { Component, props } }: Props,
) {
return (
);
}
```
Isso garante consistência e reforça o conceito de um tipo nomeado, tornando mais
fácil para os desenvolvedores e usuários de negócios restringirem suas seções
conforme desejado!
## Nota
Com a capacidade de aceitar outras seções como parâmetros, você pode criar
seções altamente modulares e personalizáveis que se adaptam a diferentes casos
de uso e tornam suas aplicações deco ainda mais poderosas e flexíveis. Boa
codificação! 🧩🚀
# null
Source: https://docs.deco.cx/pt/developing-capabilities/sections/error-fallback
Limitador de Erros lançados durante a renderização de uma Seção
# Limitador de Erros
## Visão Geral
Captura e tratamento de erro é um conceito poderoso disponível desde a versão
1.54.0, que permite lidar com erros que ocorrem durante a renderização de
componentes. Eles permitem que você lide elegantemente com erros e evite que
toda a aplicação seja interrompida devido a um erro não tratado.
Na deco, criar um limite de erro é tão simples como exportar uma função de
componente chamada `ErrorFallback` que recebe um objeto com uma propriedade:
`error`. A propriedade `error` armazena o objeto de erro que foi lançado pelo
componente.
Os pré-requisitos para fazer o seu componente funcionar com tratamento de erro
são ter as seguintes dependências nas versões iguais ou superiores às abaixo:
```json
{
"imports": {
"deco/": "https://denopkg.com/deco-cx/deco@1.54.0/",
"$fresh/": "https://denopkg.com/deco-cx/fresh@1.3.2/",
"preact": "https://esm.sh/preact@10.16.0",
"preact/": "https://esm.sh/preact@10.16.0/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.2.0",
"@preact/signals": "https://esm.sh/*@preact/signals@1.1.3",
"@preact/signals-core": "https://esm.sh/@preact/signals-core@1.3.0"
}
}
```
## Exemplo: Criando um Limitador de Exceção
Para criar um limite de erro, você pode seguir estes passos:
* Escolha a Seção selecionada (por exemplo, `ProductShelf.tsx`)
* Exporte uma função chamada `ErrorFallback`, a função deve receber um objeto
com uma propriedade: `error`.
```tsx
// ProductShelf.tsx
export interface Props {
myProp: string;
}
export function ErrorFallback({ error }: { error?: Error }) {
// Sua lógica de tratamento de erro vai aqui
// Você pode exibir uma mensagem de erro, registrar o erro ou renderizar uma interface de substituição
return (
Oops! Algo deu errado.
{error.message}
);
}
export default function ProductShelf(props: Props) {
...
}
```
Se ocorrer um erro durante a renderização de `ProductShelf`, o componente
`ErrorFallback` sera renderizado no lugar de `ProductShelf`
Lembre-se de usar os limites de erro com cuidado e envolver apenas os
componentes propensos a erros. Usar os limites de erro de forma eficaz pode
melhorar muito a estabilidade e a experiência do usuário em suas aplicações.
Caso nao haja nenhum `ErrorFallback` definido, um fallback padrao será utilizado
# null
Source: https://docs.deco.cx/pt/developing-capabilities/sections/loading-fallback
Adição de fallback de carregamento para seções
# Fallback de Carregamento
## Visão Geral
Os fallbacks de carregamento são um conceito poderoso disponível para uso desde
a versão 1.54.0, para lidar com o estado de carregamento de seções usando dados
de APIs de terceiros. Eles permitem que você lide graciosamente com estados de
carregamento e evite que toda a aplicação pare devido a alguma API de terceiros.
No deco, criar um fallback de carregamento é tão simples quanto exportar uma
função de componente chamada `LoadingFallback`.
Os pré-requisitos para fazer com que seu componente funcione são ter as
seguintes dependências em versões iguais ou superiores às listadas abaixo:
```json
{
"imports": {
"deco/": "https://denopkg.com/deco-cx/deco@1.54.0/",
"$fresh/": "https://denopkg.com/deco-cx/fresh@1.3.2/",
"preact": "https://esm.sh/preact@10.16.0",
"preact/": "https://esm.sh/preact@10.16.0/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.2.0",
"@preact/signals": "https://esm.sh/*@preact/signals@1.1.3",
"@preact/signals-core": "https://esm.sh/@preact/signals-core@1.3.0"
}
}
```
## Exemplo: Criando um Fallback de Carregamento
Para criar um fallback de carregamento, você pode seguir estes passos:
* Escolha sua Seção selecionada (por exemplo, `ProductShelf.tsx`)
* Exporte uma função chamada `LoadingFallback`.
```tsx
// ProductShelf.tsx
export interface Props {
myProp: string;
}
export function LoadingFallback() {
// Renderize spinners, esqueletos e outros espaços reservados
return (
carregando...
);
}
export default function ProductShelf(props: Props) {
...
}
```
Se `ProductShelf` usar dados provenientes de uma API de terceiros lenta, o
componente `LoadingFallback` será renderizado em seu lugar. Se nenhum fallback
de carregamento for definido, um fallback padrão será renderizado em seu lugar.
# null
Source: https://docs.deco.cx/pt/developing-capabilities/sections/redirecting-users
Redirecionando usuários a partir de uma Seção
# Realizando Redirecionamentos em Seções
Os redirecionamentos em seções permitem que você direcione eficientemente os
usuários para diferentes páginas com base em determinadas condições,
proporcionando uma experiência de navegação suave e contínua. Com o Live.ts,
você pode implementar facilmente redirecionamentos usando carregadores inline e
a função `redirect` do módulo `deco/mod.ts`.
## Visão Geral
Os redirecionamentos permitem que você evite a fase inteira de renderização,
contornando a necessidade de geração desnecessária de conteúdo quando um
redirecionamento é necessário. Eles são especialmente úteis quando você deseja
guiar os usuários para páginas específicas com base em determinados critérios,
como autenticação do usuário, geolocalização ou qualquer outra condição
personalizada.
## Implementação
Para criar um redirecionamento em uma seção, siga estes passos simples:
1. Crie um carregador inline dentro do componente da sua seção e importe a
função `redirect` do módulo `deco/mod.ts`.
```tsx
import { redirect } from "deco/mod.ts";
export default function MyComponent(props: Props) {
// Sua lógica de componente vai aqui
// ...
}
export const loader = (props: Props, req: Request) => {
// Sua condição de redirecionamento aqui
if (SUA_CONDICAO_PARA_REDIRECIONAR_USUARIO) {
const url = new URL(req.url);
url.pathname = "/seu_caminho_de_redirecionamento"; // Atualize isso com o caminho de redirecionamento desejado
redirect(url.toString()); // Você também pode usar a URL completa de qualquer lugar
}
// Retorne as props do componente
return props;
};
```
2. Dentro da função `loader`, defina a condição que determina se o
redirecionamento deve ser acionado. Se a condição for atendida, construa a
nova URL usando a classe `URL` e especifique o caminho para o qual você
deseja redirecionar.
3. Por fim, chame a função `redirect` com a URL recém-criada. Isso direcionará
instantaneamente o usuário para a página especificada sem a necessidade de
renderização adicional.
Observe que você precisa retornar algo (neste caso, as `props`) na função
`loader`, mesmo se estiver usando um redirecionamento. Isso é para garantir que
a função se comporte conforme o esperado e atenda aos requisitos do compilador
TypeScript.
## Exemplo
Digamos que você deseje redirecionar os usuários para uma página de login caso
eles não estejam autenticados:
```tsx
import { redirect } from "deco/mod.ts";
export default function MyComponent(props: Props) {
// Sua lógica de componente vai aqui
// ...
}
export const loader = (props: Props, req: Request) => {
// Verifique se o usuário não está autenticado
if (!props.isAuthenticated) {
const url = new URL(req.url);
url.pathname = "/login"; // Redirecionar para a página de login
redirect(url.toString());
}
// Retorne as props do componente
return props;
};
```
Neste exemplo, se o usuário não estiver autenticado, ele será redirecionado para
a página de login. Caso contrário, o componente continuará sendo renderizado
normalmente.
## Lembre-se
* Use redirecionamentos com cuidado e apenas quando necessário para garantir uma
experiência de usuário suave.
* Sempre teste seus redirecionamentos cuidadosamente para garantir que eles se
comportem conforme o esperado.
* Mantenha seus redirecionamentos organizados e fáceis de manter para evitar
comportamentos indesejados.
Com redirecionamentos em seções, você tem o poder de guiar os usuários de forma
perfeita em suas aplicações Live.ts com base em condições específicas. Boa
navegação! 🚀🔀
# null
Source: https://docs.deco.cx/pt/developing-capabilities/troubleshooting
Problemas comuns
## Problemas ao rodar o deno localmente
Ao rodar o projeto localmente, o `deno` exibe erros ou problemas ao executar o
site.
### Atualize o deno
Execute o comando a seguir para atualizar o deno a última versão...
`deno upgrade`
Em alguns casos muito específicos, é possível também testar outras versões do
deno especificando uma versão a ser atualizada...
`deno upgrade --version X.Y.Z`
### Limpe o cache do deno
O deno é eficiente ao fazer um cache agressivo das dependências de forma que o
tempo para reiniciar o servidor é muito rápido. Ao mesmo tempo, as dependências
em cache podem ter problemas ou erros nas versões que foram baixadas.
Assim, recomendamos limpar o cache dos arquivos relacionados:
`deno cache -r dev.ts main.ts`
Em caso de erros relacionados a elementos de tipagem ou de execução, tente
limpar também o storage local:
`deno eval 'localStorage.clear()'`
Dependendo da instalação e configuração do site, o deno pode puxar as
dependências do npm no diretório "node\_modules". Apagar este diretório pode
resolver problemas relacionados a dependências do npm.
### Verifique se outra aplicação está executando na porta 8000
Caso outra aplicação esteja executando na porta 8000, o processo do deno pode
entrar em "loop" ou apresentar uma falha de inicialização na porta em questão.
Observe se há outras aplicações executando na porta 8000.
## Minhas alterações não foram refletidas no site em produção
### Verifique se o deploy foi realizado com sucesso
No repositório do site, verifique uma marcação referente ao último *commit*. O
*deploy* deve ter sido realizado com sucesso para que o código possa ser
considerado em produção:
.
Em caso de falha, passe o cursor na sinalização de erro para ver uma indicação
do problema.
Caso o sistema tenha falhado na nossa infraestrutura, pode enviar um commit
vazio para forçar um novo *deploy* com o comando:
`git commit --allow-empty -n -m "Redeploy"`
### Verifique o seletor de ambiente
Verifique se o seletor de ambientes (preview) aponta para o endereço correto.
## Estou com erros em uma seção, página, ou funcionalidade específica
### Atualize a deco e std
Novas versões do framework da deco e do std trazem correções de falhas comuns ao
projeto:
`deno eval 'import "deco/scripts/update.ts"'`
## Um componente não está interativo, o click/botão não funciona
Todo componente interativo deve ser uma ilha. Para isso, deve estar dentro da
página `islands/` e não pode estar euma sub-pasta.
Caso o carregamento de algum JS no browser falhe, os componentes podem perder a
interatividade. Abra o `console.log` para procurar por erros de JS.
# Criando Loaders
Source: https://docs.deco.cx/pt/developing-guide/creating-loaders
Criando loaders
Agora que você aprendeu mais sobre loaders e como eles podem ser usados junto
com uma seção, vamos criar um loader que pode ser usado em diferentes seções.
## 1. Criando um Loader
Para fazer isso, vamos criar um loader separado da seção, na pasta `loaders/` do
seu projeto.
Crie o arquivo `DogFactsLoader.ts` na pasta `loaders/` do seu projeto. Ele terá
a mesma lógica do loader que criamos no tutorial anterior, mas temos que lembrar
de definir a interface Props e exportar o loader como padrão.
```tsx
export type DogFacts = string[];
export interface Props {
numberOfFacts?: number;
}
async function loader(
{ numberOfFacts = 1 }: Props,
_req: Request,
): Promise {
const { facts } = await fetch(
`https://dogapi.dog/api/facts?number=${numberOfFacts ?? 1}`,
).then((r) => r.json());
return facts;
}
export default loader;
```
## 2. Usando o Loader em uma Seção
Agora que criamos o loader, podemos usá-lo em uma seção. O importante aqui é que
uma das props da seção deve corresponder ao tipo de retorno do loader.
Modifique o arquivo `DogFacts.tsx` na pasta `sections/` do seu projeto.
```tsx
import type { DogFacts } from "../loaders/DogFactsLoader.ts";
// Tipo de Props que será configurado no Admin do deco.cx
export interface Props {
title: string;
dogFacts?: DogFacts;
}
export default function DogFactsSection(
{ title, dogFacts }: Props,
) {
return (
{title}
{dogFacts?.map((fact) =>
{fact}
)}
);
}
```
Agora, em vez de ter um loader embutido, a seção recebe os dados como uma prop,
e como o loader retorna o mesmo tipo que a prop dogFacts da seção, o Admin
reconhece o loader dogFacts como o loader para a seção DogFacts.

## É isso!
Você criou com sucesso um loader que pode ser usado em diferentes seções.
Continue lendo para ver o que mais você pode desenvolver com deco.
# Editando seções
Source: https://docs.deco.cx/pt/developing-guide/editable-sections
Editando seções
## Introdução às Seções (dev)
Uma Seção representa um elemento de UI configurável para um site deco. É
essencial entender o que isso significa para um desenvolvedor.
Uma Section é um código `tsx` dentro da pasta `sections` e que:
* é um componente [Preact](https://preactjs.com/)
* tem propriedades serializáveis
* exporta o tipo de suas propriedades
Um componente Preact é uma função exportada por padrão (`export default`). Ele
recebe propriedades, retorna JSX e é invocado durante cada renderização do
elemento definido.
Vamos explorar como podemos manipular essas seções e ver as mudanças refletidas
na interface do Admin.
## 1. Abra a seção Hero
Como exemplo, abra a seção `Hero.tsx` na interface do Admin do site que você
criou em um [tutorial anterior](https://deco.cx/docs/pt/getting-started/creating-a-site).
Clique no ícone `>` na barra direita para ver o código da seção.
O código deste elemento é escrito em HTML com JavaScript, como mostrado no
exemplo abaixo.

Observe os tipos exportados neste arquivo. Esses mesmos tipos são acessíveis no
formulário de propriedades da seção quando você clica no ícone de lista na barra
direita.

**Seção e seus tipos de propriedades**
## 2. Execute seu site localmente
Siga os passos de [configuração do ambiente](https://deco.cx/docs/pt/developing-guide/setup) e
execute seu projeto localmente para ver as mudanças que você fizer no código
refletidas na interface do Admin.
## 3. Adicione uma nova propriedade à seção Hero
Modifique o código de `sections/Hero.tsx` para receber uma nova propriedade
opcional, o `size` (tamanho) de um botão CTA. Adicione ao tipo `CTA` uma nova
propriedade, `size`, que deve ser uma dessas strings: "xs", "sm", "md" e "lg".
```tsx
export interface CTA {
id?: string;
href: string;
text: string;
outline?: boolean;
size?: "xs" | "sm" | "md" | "lg";
}
```
Esse tipo de campo indica ao Admin que essa propriedade só pode assumir esses
valores, fazendo a plataforma mostrar um componente de seleção para editar esse
campo.
Você pode ler mais sobre esses formatos e tipos de campo na
[documentação de Widgets](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets).
Vamos adicionar um botão CTA na nossa seção Hero para ver a modificação:

Agora o CTA tem o campo de tamanho:

Também vamos modificar o conteúdo JSX para fazer o tamanho do botão CTA mudar de
acordo com a opção selecionada no formulário do Admin:
```tsx
...
...
```
Com essa mudança, você pode ajustar o tamanho do botão através do formulário do
Admin:

## 4. Pronto para começar!
Agora você pode configurar `props` para as Seções do seu site e ver como elas
são renderizadas. A pré-visualização será automaticamente atualizada se você
modificar o código da Seção localmente.
Para publicar as mudanças, faça um *git push* para a branch principal ou
publique seu ambiente diretamente na interface do Admin.
# Newsletter com HTMX e Deco Records
Source: https://docs.deco.cx/pt/developing-guide/examples
Newsletter com HTMX e Deco Records
## Principais ferramentas
* Deco.cx como hospedagem e CMS.
* Deco Records como banco de dados SQLite, utilizando o
[Drizzle ORM](https://orm.drizzle.team/)
* App da Resend para envio de e-mails de confirmação. API de envio de e-mails
que oferece um plano gratuito de 3.000 e-mails por mês.
## Configurações necessárias
1. Criar um site na [deco.cx](https://deco.cx/new)
2. Configurar o [Deco Records](https://deco.cx/docs/en/reference/deco-records)
> Para esse tutorial, criamos uma tabela "newsletter" com as colunas `id`,
> `email`, `confirmed_at`, `confirmation_key`.
3. Instalar a app da Resend no menu "Apps", configurando a API Key. Ao instalar
a app Resend na deco, você encontrará instruções de como fazer isso.
## Criando as sections utilizadas
Duas sections foram utilizadas nesse tutorial:
1. `newsletterSubsbribe.tsx`: Formulário de inscrição na Newsletter (campo de
e-mail) + [action](https://deco.cx/docs/pt/concepts/action) inline que
realiza o processo de inclusão do e-mail no banco de dados e envio do e-mail
usando a app da Resend. Principais componentes da section:
```tsx
export async function action(
props: Props,
req: Request,
ctx: AppContext & RecordsApp & ResendApp,
): Promise {
const form = await req.formData(); // Obtém os dados do banco de dados
const email = `${form.get("email") ?? ""}`;
if (!email) {
console.log("Email is empty");
return { ...props, submissionResponse: { email: "" } };
}
const drizzle = await ctx.invoke("records/loaders/drizzle.ts"); // Carrega o drizzle para interagir com o banco de dados
try {
const recs = await drizzle // Verifica se o email já está registrado no banco de dados
.select({ email: newsletter.email })
.from(newsletter)
.where(eq(newsletter.email, email));
if (recs.length) {
return {
...props,
submissionResponse: { error: "Email already exists.", email },
};
}
const confirmationKey = crypto.randomUUID(); // Gera uma chave de confirmação única para a verificação
await drizzle.insert(newsletter).values({ // Insere o novo registro de newsletter no banco de dados
email,
confirmed_at: null,
confirmation_Key: confirmationKey,
});
await ctx.invoke("resend/actions/emails/send.ts", {
subject: `Personal Blog - Confirm your subscription`,
from: no-reply@blog.owner
html: `
Thanks for subscribing!
Click here to confirm your subscription.`,
to: email,
});
return { ...props, submissionResponse: { email: "" } };
} catch (e) {
console.log(e);
ctx.monitoring?.logger?.error(e);
return {
...props, submissionResponse: { error: "System error", email },
};
}
}
export function loader(props: Props) {
return props;
}
```
E no formulário contém a utilização do HTMX para realizar a requisição de
forma assíncrona e atualizar apenas a seção necessária.
```tsx
;
```
2. `newsletterConfirmation.tsx`: Section a ser incluída na página `/confirm` do
site para que os usuários possam confirmar a inscrição e receber um feedback
positivo. O principal uso dessa section foi a utilização do loader para
processar os dados:
```tsx
export const loader = async (
props: Props,
req: Request,
ctx: AppContext & RecordsApp,
) => {
const url = new URL(req.url);
const reallyQs = url.searchParams.get("really");
if (!reallyQs) {
return props;
}
const confirmationKey = url.searchParams.get("key");
if (!confirmationKey) {
return { ...props, error: "No confirmation key." };
}
const drizzle = await ctx.invoke("records/loaders/drizzle.ts");
await drizzle
.update(newsletter)
.set({
confirmed_at: new Date().toISOString(),
confirmation_key: null,
})
.where(eq(newsletter.confirmation_key, confirmationKey ?? ""));
return { ...props, really: true };
};
```
## Conclusão
Este tutorial demonstra como implementar um sistema de inscrição em newsletter
utilizando as ferramentas deco.cx, Deco Records e Resend. A solução apresentada
oferece um fluxo completo, desde a captura do e-mail do usuário até a
confirmação da inscrição, garantindo a integridade dos dados e a experiência do
usuário. A utilização de tecnologias modernas como HTMX e Drizzle ORM
proporciona uma implementação eficiente e de fácil manutenção. Este sistema pode
ser facilmente adaptado e expandido para atender às necessidades específicas de
diferentes projetos web.
# Pegando Dados
Source: https://docs.deco.cx/pt/developing-guide/fetching-data
Aprenda como carregar dados usando Loaders e Sections, permitindo que usuários de negócios personalizem a busca.
Buscar dados de APIs é um requisito comum ao criar sites ou aplicações. A
*deco.cx* oferece uma solução de *data-fetching* que ocorre **no server-side** e
é flexível para permitir que os usuários de negócios configurem como os dados
são buscados, da mesma forma que configuram `props` das Sections.
Neste tutorial, você aprenderá como buscar dados de uma API externa e injetá-los
em uma Section usando [Loaders](https://deco.cx/docs/pt/concepts/loader).
## O que vamos construir
O exemplo que usaremos é simples, mas tem complexidades comuns à outros casos:
* Fazer *fetch* de fatos sobre cachorros usando a [Dog API](https://dogapi.dog/)
**permitindo ao usuário configurar quantos fatos serão retornados** no Admin
da *deco.cx*.
* Apresentar esses fatos em uma Section.
*Visualização da Section DogFacts mostrando os dados retornados da API*
*Dados retornados da API Dog Facts sendo chamada no browser*
## 1. Criando a Section
Primeiro, vamos criar uma Section que renderizará os dados buscados da API. Crie
a seção `DogFacts.tsx` na pasta sections/ do seu projeto.
Se executarmos um http request para a API da Dog Fact veremos que ele retorna um
JSON no seguinte formato,
> Abra no seu browser:
> [esta URL com parâmetros para a API](https://dogapi.dog/api/facts?number=1)
```json
{
"facts": [
"The Labrador is so popular, in 2006 there were approximately
3-5 times more Labs as there were German Shepherds or Golden Retrievers."
],
"success": true
}
```
Perceba que a única coisa que nos importa são os facts, logo vamos criar nossa
section preparada para receber esses facts re renderiza-los da maneira que
desejarmos.
Para isso, vamos criar um tipo `DoctFact` que contém apenas uma propriedade
chamada `fact` que é a `string` representada pela mensagem.
Vamos ver isso em ação criando uma nova Section:
Cole o seguinte código:
```tsx
export interface DogFact {
fact: string;
}
export interface Props {
title: string;
dogFacts: string[];
}
export default function DogFacts({ title, dogFacts }: Props) {
return (
{title}
{dogFacts.map((fact) =>
{fact}
)}
);
}
```
> Nesse momento podemos rodar o `deno task start` e verificar no nosso admin que
> esse componente já consegue ser utilizado com dados estáticos, oque não faz
> muito sentido para nosso caso de uso.
## 2. Criando o Loader e testando a Section
Agora vamos criar um Loader que buscará os dados da Dog Fact API e os passará
para a Section.
Os Loaders permitem que você defina como os dados são buscados e transformados
antes de serem passados para uma Section. Eles são **funções regulares de
Typescript** que podem usar funções *async* como `fetch`. Os Loaders podem ser
"plugados" em uma Section via uma das `props` da Section, e isso acontece com
base no **tipo de retorno do Loader** (o tipo de retorno do Loader é o tipo de
entrada da Section).
1. Defina qual será as `Props` de input do seu loader.
2. Exporte uma função chamada `loader` dentro do mesmo arquivo da sua section.
No nosso caso, vamos deixar configurável qual número de facts que vamos mostrar
no nosso componente. Perceba que agora, o que aparecerá parece ser configurado
não será mais as props da section mas sim as props do seu loader.
```tsx
import type { SectionProps } from "deco/mod.ts";
// Props type that will be configured in deco.cx's Admin
export interface Props {
title: string;
numberOfFacts?: number;
}
export async function loader(
{ numberOfFacts, title }: Props,
_req: Request,
) {
const { facts: dogFacts } = (await fetch(
`https://dogapi.dog/api/facts?number=${numberOfFacts ?? 1}`,
).then((r) => r.json())) as { facts: string[] };
return { dogFacts, title };
}
export default function DogFacts(
{ title, dogFacts }: SectionProps,
) {
return (
{title}
{dogFacts.map((fact) =>
{fact}
)}
);
}
```
> Observação: O tipo `SectionProps` é um tipo auxiliar usado para inferir o tipo
> de retorno do loader.
## 3. Testando a Section
1. Execute o servidor localmente com
`DECO_ENV_NAME={environment_name} deno task start`.
2. Acesse `https://deco.cx/admin` no seu site e certifique-se de que seu
ambiente está selecionado no Seletor de Ambiente no canto superior direito do
Admin.
3. Vá para `Sections` e procure por DogFacts na barra lateral esquerda.
4. Configure as props do Loader selecionado (`numberOfFacts`) com um número
desejado (por exemplo, 4).
Agora, vamos ver isso funcionando conectando-o a uma Section.

**É isso!** Agora você criou uma Section que exibe os dados obtidos de um API
externa usando um Loader, tornando tudo configurável por usuários de negócios
como desejado. Recomendamos exportar filtros e *sort* nos `props` do Loader para
torná-lo mais reutilizável no Admin da *deco.cx*.
## Leitura adicional
Os loaders são componentes poderosos para lidar com dados dinâmicos e resolvem a
maior parte dos requisitos quando lidamos com dados vindos de API. A plataforma
da `deco.cx` possui uma outra infinidade de casos de usos relacionados com dados
dinâmicos que podemos utilizar.
* [Componentes Universais](https://deco.cx/docs/pt/developing-capabilities/section-properties/standard-data-types)
* [Conceitos básicos: Loaders](https://deco.cx/docs/pt/concepts/loader)
# Go-Live com Teste A/B
Source: https://docs.deco.cx/pt/developing-guide/go-live-ab-testing
Go-Live com Teste A/B
Trabalhar com dois ambientes ao mesmo tempo é algo sensível em termos de
consistência de dados. Recomendamos que seja seguido um processo detalhado e
cuidadoso, prestando atenção a alguns pontos, como:
* Replicar o GTM de forma idêntica em ambos os ambientes
* Atualizar ambos os ambientes ao longo do teste
* Garantir a igualdade de features
Na deco.cx, existem alguns métodos de teste antes de realizar a migração
completa de um site.
## Método de subdomínio
O método de subdomínio, consiste em associar o site construído na deco.cx a um
novo subdomínio.
Exemplo: Meu site atual `www.deco.cx`, vamos associar o novo site ao domínio
`store.deco.cx`.
### Como fazer:
1 - Registrar um sub-domínio na [deco.cx](https://deco.cx)
* [Doc](https://deco.cx/docs/en/getting-started/custom-domains/)
2 - Criar um script para divisão de tráfego
* Crie um loader na deco.cx, como
[esse](https://gist.github.com/guitavano/aca72370b74081289d5d2b86143828e6)
* Preencha as informações desse loader na sua app `site`
* Insira na tag `` do seu site atual, esse loader em uma tag `
```
Esse script, irá sortear os usuáriso para mantê-los no site ou redirecioná-los
para o subdomínio.
### Como medir o resultado?
* Configurar o G.A e o GTM em ambos os sites
#### Vantagens
* O cliente só paga a infraestrutura proporcional ao uso
* Setup simples
#### Desvantagens
* O cliente final vê uma URL diferente
* A divisão de tráfego é feita com Javascript no Front
## Método de Proxy da deco.cx
O método de proxy consiste em manter todo o tráfego no mesmo domínio, mas
realizar um proxy transparente para parte dos usuários.
Repare que dessa forma, você precisa colocar o seu antigo site em outro domínio,
para que a deco.cx utilize-o para o Proxy.
### Como fazer:
Facilitamos a ativação desse proxy com esse fluxo:
1 - No painel deco.cx, acesse `Apps`
2 - Abra o app `site`
3 - Você deve ver essa configuração:
O segmento da imagem, é o `Random`, com split de 50%, mas você pode utilizar
outros segmentos.
### Como medir o resultado?
* Configurar o G.A e o GTM em ambos os sites
* Acompanhar os resultados na deco.cx
Para acompanhar os resultados na deco.cx, o Matcher a ser utilizado precisa ser
criado através da aba de Experiments, confira como em
[Teste A/B](https://deco.cx/docs/pt/developing-capabilities/apps/ab-test).
Além disso, repare que nas configurações, existe a opção `Scripts to include`;
selecione e inclua o script `DecoAnalytics`.
#### Vantagens
* Mantem a experiência toda no mesmo domínio
* Setup de divisão de tráfego pronto
* Setup de Analytics pront
#### Desvantagens
* Paga o custo de todo tráfego, independente do escalonamento
## Método de Proxy externo
Este método, é o inverso do proxy na deco.cx: a responsabilidade de dividir o
tráfego e fazer o proxy é do antigo website.
> Nota: Para lojas VTEX, deco.cx está construindo um APP no Vtex IO para
> realizar esse proxy
Caso esteja em dúvida sobre como desenvolver esse proxy na sua tecnologia,
estamos no [Discord](https://deco.cx/discord) para ajudar.
#### Vantagens
* O cliente só paga a infraestrutura proporcional ao uso
#### Desvantagens
* Setup não vem pronto, a depender da tecnologia
## Informações extras
### Configuração GTM
Para auxiliar a configuração dos eventos no GTM, recomendamos a consulta do
cookie `deco_matcher...`, que indica em qual versão o usuário está.
### Orderform VTEX
Como fonte extra de dados, recomendamos a inserção no OrderForm de uma marcação
no marketingData, indicando em qual versão o usuário está, pois essa informação
vai para o painel de pedidos da VTEX.
* [Script exemplo](https://gist.github.com/guitavano/6de5f1068c85800b0702937b97c51ef2)
# Criando uma Section
Source: https://docs.deco.cx/pt/developing-guide/hello-world
Criando uma Section
Agora que você está mais familiarizado com Sections e como elas são usadas no
admin, vamos criar uma Section do zero. Neste guia, você aprenderá a criar uma
Section, a adicionar propriedades a ela e a estilizá-la com seus temas.
Abra a pasta do seu site em uma IDE e execute as seguintes ações:
## 1. Crie um arquivo `.tsx` na pasta `sections/`
Crie um arquivo `.tsx` na pasta `sections/` em seu Site com o nome desejado para
Section (*e.g*: `Post.tsx`).
A Section é um componente [Preact](https://preactjs.com/) que é configurável no
Admin. Para que a Section seja visível no Admin, é preciso criar esse componente
na pasta `sections/` ou em algum de seus sub-diretórios.
## 2. Exporte o componente
Exporte um componente [Preact](https://preactjs.com/) **usando
`export default`** como o exemplo abaixo:
`sections/Post.tsx`
```tsx
export interface Props {
title: string;
}
export default function Post({ title }: Props) {
return (
{title}
This is an example section
);
}
```
**Pronto!** A Section foi criada localmente no seu projeto.
## 3. Visualize a Section no Admin
Execute o projeto localmente como foi feito anteriormente no
[setup](https://deco.cx/docs/pt/developing-guide/setup). Ao selecionar seu ambiente local no
Admin, você poderá visualizar a nova Section na biblioteca de Sections
(**Sections**) e adicioná-la a uma página.

## 4. Adicionando propriedades à Section
Vamos adicionar três novas propriedades ao nosso componente `Post`, uma para
imagem (`photo`), outro para o corpo da postagem (`post`) e um para a hora da
postagem.
```tsx
import type { ImageWidget } from "apps/admin/widgets.ts";
import Image from "apps/website/components/Image.tsx";
export interface Props {
/**
* @title Post image.
*/
photo?: ImageWidget;
/**
* @title Post body.
* @format textarea
*/
post: string;
/**
* @title Publish date.
* @format datetime
*/
datetime: string;
/**
* @title Post title.
*/
title: string;
}
export default function Post({ title, photo, datetime, post }: Props) {
return (
{photo && (
)}
{title}
Published at: {datetime}
This is an example section
{post}
);
}
```
Uma Section pode ter como propriedade qualquer elemento que seja serializável, e
interpretável no formulário de propriedades no admin da deco. Isto inclue:
* `strings` e `numbers`
* Tipos simples de objetos serializáveis
* Tipos gerados de união, extensão, `Pick` ou `Omit`
* `Sections` ( `import { Section } from "deco/blocks/section.ts"` )
* `ImageWidget` (`import type { ImageWidget } from "apps/admin/widgets.ts";`) e
outros components do admin
* Arrays dos tipos indicados acima
Além dos tipos acima, é possível anotar algumas propriedades para que o
formulário do admin altere o mecanismo de inserção ou para determinar alguns
aspectos do comportamento da propriedade (através da anotação `@format`, por
exemplo). Leia mais sobre
[essas anotações aqui](https://deco.cx/docs/pt/developing-capabilities/section-properties/widgets)
## 5. Visualizando as novas propriedades no Admin
Com o projeto executando localmente, abra novamente a Section no Admin. Você
verá as novas propriedades adicionadas ao componente `Post`. É possível ver que
o admin prepara componentes próprios de formulário para a inserção de imagens,
data, bem como sinaliza o que é cada campo a partir do `title` indicado em
código.

## 6. Tematizando a Section
### 6.1 Tema do Site
No projeto base deco, é possível acessar uma Section especial, a `Theme.tsx`.
Esta section define tokens e nomes especiais de classes que podem ser utilizadas
por outras Sections seguindo a estrutura da ferramenta DaisyUI. Dentro do
`Theme.tsx` é possível observar alguns tokens como o de cores principais:
```tsx
export interface MainColors {
/**
* @format color
* @title Base
* @default #FFFFFF
*/
"base-100": string;
/**
* @format color
* @title Primary
* @default #003232
*/
"primary": string;
/**
* @format color
* @title Scondary
* @default #8C3D3D
*/
"secondary": string;
/**
* @format color
* @title Tertiary
* @default #00FF7F
*/
"tertiary": string;
}
```
As cores de cada token podem ser alteradas no Admin, na aba de Themes. Nela,
você pode alterar as cores do seu tema atual ou criar um novo tema.

### 6.2 Tema de uma página
Além do tema do site, é possível alterar o tema de uma página específica. Para
isso, basta acessar uma página específica no Admin adicionar a section do tema
desejado.


Neste caso, adicionamos na página My New Page a Section do tema Groovy Vibes.
Esta página em específico agora tem um tema diferente do restante do site.

### 6.3 Estilizando a Section
Adapte a classe de postagens para fazer uso de alguns tokens. Por exemplo, o
título principal da postagem agora segue a cor primária do tema.
```tsx
import type { ImageWidget } from "apps/admin/widgets.ts";
import Image from "apps/website/components/Image.tsx";
export interface Props {
/**
* @title Post image.
*/
photo?: ImageWidget;
/**
* @title Post body.
* @format textarea
*/
post: string;
/**
* @title Publish date.
* @format datetime
*/
datetime: string;
/**
* @title Post title.
*/
title: string;
}
export default function Post({ title, photo, datetime, post }: Props) {
return (
{photo && (
)}
{title}
Published at: {datetime}
This is an example section
{post}
);
}
```
Agora, a Section `Post` segue o tema do site (ou da página) e utiliza as cores
definidas no tema.

# Interatividade com HTMX
Source: https://docs.deco.cx/pt/developing-guide/htmx
Interatividade com HTMX
Este tutorial vai te guiar na integração do HTMX ao seu projeto deco, permitindo
maior interatividade com o mínimo de JavaScript. Vamos criar um contador como
exemplo para ver como deco.cx integra com HTMX.
## O que é o HTMX?
HTMX permite acessar recursos modernos do navegador diretamente do HTML,
facilitando a construção de aplicações web interativas com menos JavaScript.
## Passo 1: Adicionando HTMX ao Seu Projeto
Primeiro, você precisa incluir a biblioteca HTMX no seu projeto. Você pode fazer
isso adicionando a seguinte tag de script ao seu HTML:
```html
```
## Passo 2: Criando a Versão Preact do Contador
Vamos criar um componente Preact para o contador e ver a diferença para a versão
com HTMX:
```tsx
import { useState } from "preact/hooks";
export default function Section() {
const [count, setCount] = useState(0);
return (
{count}
);
}
```
Aqui, estamos usando o hook `useState` do Preact para gerenciar o estado do
contador e o evento `onClick` para atualizar o contador quando os botões são
clicados.
## Passo 3: Criando a Versão HTMX do Contador
Na versão HTMX, não usaremos mais o hook `useState` nem o evento `onClick`. Ao
usar HTMX, precisamos de uma rota para cada estado da UI, então faremos uma
solicitação ao servidor para atualizar o estado do contador.
É aí que o [hook `useSection`](https://deco.cx/docs/pt/api-reference/use-section) é útil. Este
hook cria automaticamente rotas para renderizar seus estados de UI sem exigir
que os desenvolvedores lidem manualmente com o roteamento.
Vamos ver o que muda na versão HTMX:
```tsx
import { useSection } from "deco/hooks/useSection.ts";
export default function Section({ count = 0 }: { count: number }) {
return (
{count}
);
}
```
Para atualizar o estado, como mencionado antes, estamos usando `hx-get` com o
hook `useSection`. O atributo `hx-get` faz uma solicitação GET para a URL
retornada pelo hook `useSection`. A resposta é um novo HTML com o novo estado da
UI do contador. O atributo `hx-target` define o elemento alvo onde a resposta
será inserida, neste caso, a seção mais próxima do botão. O atributo `hx-swap`
define como a resposta será inserida, neste caso, substituindo todo o elemento
da seção pela resposta.
Para ilustrar a diferença entre as versões Preact e HTMX, vamos usá-las e ver
como se comportam na aba de Network das ferramentas de desenvolvedor do
navegador.
Enquanto a versão Preact atualiza o estado do contador localmente, a versão HTMX
faz uma requisição ao servidor para atualizar o estado do contador.


## Conclusão
HTMX é uma ferramenta poderosa que pode simplificar o processo de adicionar
interatividade às suas aplicações web. Usando HTMX, você pode reduzir a
quantidade de JavaScript que precisa escrever e manter, tornando seu código mais
limpo e gerenciável.
Para mais informações, confira a [documentação do HTMX](https://htmx.org/docs/)
e a [documentação do deco.cx](https://deco.cx/docs/).
# Configuração do ambiente.
Source: https://docs.deco.cx/pt/developing-guide/setup
Configuração do ambiente.
* Leia o guia em **Comece agora** para entender os conceitos base e a ferramenta
de admin da deco
* **Importante**, é possível acessar [nosso Discord](https://deco.cx/discord)
para reportar dúvidas ou problemas com a *deco.cx*. Participe também da nossa
comunidade!
## Tópicos
1. Tecnologias utilizadas na deco
2. Comece a desenvolver com a deco
3. Desenvolvendo com a deco
## Tecnologias utilizadas na deco
Ao criar um site ou loja online com a *deco.cx*, o usuário tem a flexibilidade
de criar [Sections](https://deco.cx/docs/pt/concepts/section) e
[Loaders](https://deco.cx/docs/pt/concepts/loader) que atendem às suas necessidades exclusivas.
Para ajudá-la a criar esses componentes com facilidade e rapidez, contamos com
um conjunto de tecnologias poderosas e eficientes.
Nossa pilha de tecnologia é focada em **simplicidade e desempenho**, tornando-a
acessível a desenvolvedores com experiência anterior em HTML, CSS, JavaScript e
React. Estas são as principais ferramentas que usamos para alimentar os sites
deco.cx:
### [Preact](https://preactjs.com/)
**Preact** é uma alternativa rápida e leve ao [React.js](https://reactjs.org/),
usado para renderizar componentes de UI no servidor e no cliente. Ele usa *JSX*
para criar componentes da web e geralmente é bem simples de aprender.
### [Tailwind](https://tailwindcss.com)
**Tailwind** é uma solução de estilos CSS baseada em classes utilitárias, o que
o torna ideal para iniciantes. O Tailwind também é otimizado para performance.
### [Deno](https://deno.com/deploy)
O **Deno** é um ambiente de execução JavaScript e TypeScript. É usado para fazer
Sites na deco, escritos em Typescript, executados por um servidor. Deno é
semelhante a Node.js (*curiosidade*: eles foram
[criados pela mesma pessoa](https://www.youtube.com/watch?v=M3BM9TB-8yA)).
### [Fresh](https://fresh.deno.dev)
O **Fresh** é um framework web fullstack (backend e frontend) para
desenvolvedores JavaScript e TypeScript. Foi projetado para tornar fácil a
criação de aplicações web de alta qualidade, alta performance e altamente
personalizáveis.
## Comece a desenvolver com a deco
### Ferramentas necessárias
A única configuração necessária para codificar sites *deco.cx* é **instalar o
Deno** em sua máquina. Para instalar o Deno, siga as
[instruções na página deno.land](https://deno.land/manual/getting_started/installation).
> Certifique-se de manter o deno atualizado! Caso já tenha o deno instalado,
> rode o `deno upgrade` para atualizá-lo.
Recomendamos fortemente o uso do
[Visual Studio Code](https://code.visualstudio.com/download) como IDE e do
[Git](https://github.com/git-guides/install-git) para controle de versão.
{/* ## Teste a deco localmente (opcional)!
A deco oferece um mecanismo para testar e explorar nosso sistema sem a
necessidade de subir código ou fazer um deployment na nossa infraestrutura. Para
isso, acesse [o Deco Play](https://play.deco.cx/)
 */}
### 1. Crie um site deco.cx
Siga o tutorial de
[Criar um Site Deco](https://deco.cx/docs/pt/getting-started/creating-a-site).
### 2. Clone o repositório do seu site
Aceite o convite para se juntar ao repositório criado para o seu Site. Esse
convite é enviado para o endereço de e-mail do seu perfil do Github.
Caso não tenha utilizado uma conta do github para entrar no admin ou caso não
tenha recebido um convite, é possível adicionar uma conta do github como
colaborador do Site na aba Configurações do site no Admin.
{/*  */}

Use o comando `git clone` para baixar o código do site para o seu máquina.
Recomendamos o uso de SSH. Abra o terminal e execute o comando:
```bash
git clone git@github.com:deco-sites/site-name.git
```
**Lembre-se de alterar `site-name` para o nome do seu site.**
Se preferir, é possível clonar o repositório usando outros métodos, como *git
https*, por meio da ferramenta *Github* ou através de uma IDE. Na página do
repositório no *Github* há detalhes sobre algumas diferentes maneiras para fazer
o clone.
### 3. Executar servidor local
Para rodar seu site localmente, editar e ver as mudanças no Admin, você precisa
ter um ambiente local (um ambiente com `localhost` como host). Para isso, você
pode usar o ambiente `localhost` criado por padrão ou criar um novo.
#### 3.1 Crie um novo ambiente
Abra a aba de Releases e clique no botão Novo ambiente no Admin.

#### 3.2 Defina o nome e o host do seu ambiente
Escolha um nome para o seu ambiente e defina seu host como localhost.

#### 3.3 Execute seu site localmente
Copie o comando mostrado depois da criação do ambiente e cole-o no seu terminal
na pasta do site.


Aguarde a inicialização do projeto. Na primeira execução, o deno irá baixar e
realizar um cache das dependências do projeto, e a deco irá preparar detalhes do
site.
O site estará acessível em https\://\{nome-do-ambiente}--\{nome-do-site}.deco.site.
{/* > Alguns browsers impedem acessar ou executar código no domínio `localhost`!
> Desative proteções de acesso ou privacidade do browser para acessar esse
> endereço. */}
Caso o código de alguma seção em uso na página inicial do site seja alterado,
isto será refletido no endereço acima.
#### 3.4 Publicando alterações
Considerando que você escolheu o Deco Hosting para o deploy de seu site, o
processo de *deploy* em development é muito simples: apenas fazer um *git push*
das alterações na *branch* ***main***.
Você também pode publicar seu ambiente no próprio Admin clicando no botão de
Publicar agora, na página do seu ambiente.

## Agora você pode começar a criar sites cada vez mais do seu jeito! :)
Continue estando a deco para entender o potencial e como criar ou alterar
sections, loaders e outros elementos da deco para criar sites e experiências
cada vez ,mais personalizadas.
Certifique-se de se juntar ao nosso
[comunidade no Discord](https://deco.cx/discord). Acompanhe as novidades e
continue evoluindo junto com a gente!
# Adicionando um App
Source: https://docs.deco.cx/pt/getting-started/adding-an-app
Adicionando um App
Nesta documentação, vamos te guiar na adição de um `App` ao seu site. Um `App`
permite que você integre facilmente novas funcionalidades, seções e recursos ao
seu site.
## 1. Acessar a Página de Apps
Para adicionar um app ao seu site, clique na aba Apps. Você verá uma lista de
todos os apps disponíveis. Neste caso, vamos adicionar o Weather App.
## 2. Instalar o App
Clique no botão de switch para instalar o app no seu site.

O Weather App fornece uma seção que exibe uma mensagem com a temperatura atual.
Além da seção, este app também inclui um loader, uma função TypeScript que
retorna dados tipicamente utilizados em Sections. Este loader específico obtém a
temperatura de um local determinado (ou da localização atual se nenhum local for
especificado). Vamos usar ambos e ver como podem ser integrados.
## 3. Usar as Funcionalidades do App
### 3.1 Vá para a Seção WhatsTheTemperature
Navegue até a Página de Seções e clique na Seção WhatsTheTemperature. Você pode
filtrar a lista pelo app.

Abra as propriedades da seção. A única propriedade que esta seção possui é a
temperatura, que é um número representando a temperatura em Celsius.
### 3.2 Configure a Seção para Usar o Loader do App
Clique no campo Temperatura para escolher como você vai fornecer a informação de
temperatura.

Você tem três opções:
1. **Entrada Manual**: Forneça um número arbitrário para a temperatura.

2. **Valor Padrão**: Deixe o campo de temperatura em branco. A seção aceita um
valor nulo, e uma temperatura fixa padrão será exibida.

3. **Usar o Loader**: Utilize o loader disponibilizado pelo Weather App.

Se você não fornecer latitude e longitude, o loader buscará a temperatura da
sua localização atual. Alternativamente, fornecendo a latitude e a longitude
de um local específico, será retornada a temperatura atual desse local:

> Parece que está um pouco frio na Groenlândia.
## 4. Usar a Seção em Suas Páginas
Agora você pode usar a seção configurada nas páginas do seu site, assim como fez
em [um tutorial anterior](https://deco.cx/docs/pt/getting-started/creating-a-new-page). É isso!
Aproveite para explorar este e outros apps no deco.cx!
# Gerenciando Mudanças e Publicando
Source: https://docs.deco.cx/pt/getting-started/changes-and-publishing
Aprenda como restaurar versões anteriores do seu site
É muito importante ter controle e autonomia para gerenciar suas páginas e blocos
e ter a capacidade de fazer e desfazer alterações facilmente, se necessário. Com
isso em mente, o *deco.cx* permite que você crie e gerencie **ambientes**.
## Ver Alterações e Publicar
Vamos dar uma olhada nas mudanças que fizemos neste ambiente. Clique no dropdown
e selecione a opção staging. Você verá esta página, mostrando o que foi alterado
em comparação com o site em produção. No nosso caso, adicionamos uma nova página
com algumas seções. Essa diferença é exibida via JSON, que representa o estado
do site de forma estruturada.

A partir daqui, você pode publicar nossas mudanças para a produção clicando no
botão "Publicar agora" ou no botão "Publicar" ao lado do dropdown do ambiente.
### Rebaseando suas Alterações
Ao publicar com múltiplos ambientes, pode ser necessário mesclar suas alterações
com as feitas em outros ambientes. Por exemplo, se você estiver editando seu
site no seu novo ambiente, `maria`, enquanto um colega estiver editando no
ambiente `staging`, e seu colega publicar suas mudanças, você precisará rebasear
seu ambiente para incorporar as novas mudanças que agora estão em produção.
Nesse cenário, em vez de ver o botão "Publicar agora" na página de Lançamentos,
você verá um botão "Rebase", como mostrado abaixo.

Clique neste botão para incorporar as mudanças de produção no seu ambiente.
Depois de rebasear, você pode publicar suas alterações clicando no botão
"Publicar agora".
# Criando uma Página
Source: https://docs.deco.cx/pt/getting-started/creating-a-new-page
Aprenda como criar páginas na deco.cx sem precisar de código
Agora vamos criar uma nova página para o seu site. O processo é muito simples:
## 1. Acesse a aba de Páginas
Páginas têm um space dedicado no Admin do Deco.cx, acessível pela barra lateral.

Nesta página, você pode ver todas as páginas publicadas no site, junto com os
caminhos pelos quais elas são acessíveis aos seus usuários.
Aqui você pode clicar no botão "Criar nova página" para criar uma página.
> Alternativamente, você pode clicar no botão "Criar página" na Página Inicial
> do Site ou digitar `/new page` na barra de comando localizada no topo central
> da página do Admin.
## 2. Dê um nome e um caminho à página
Preencha o formulário de criação de página com as seguintes informações:
* **Nome:** nome significativo para entender o que essa página representa. Não
afeta a interface do usuário ou os metadados da página.
* **Path:** representa a URL que aquela página estará acessível para seus
usuários. Pode ser estático (por exemplo: `/posts`) ou dinâmico (por exemplo:
`/posts/:slug`, `/search/*`), seguindo o esquema
[URLPattern](http://mdn.io/urlpattern).
* **Template** (opcional): selecione uma página já existente e comece a partir
dela.
Aqui, vamos criar uma página em branco.

## 3. Edite o conteúdo da página
Agora é possível editar e adicionar novas Sections disponíveis em seu site e
configurar a página do jeito que você quiser.
Para adicionar um novo componente à página, clique no botão "Adicionar Seções"
no editor e explore todas as opções disponíveis. Seções são componentes de UI
(pequenas partes do site) que podem receber propriedades e serem editadas
através de um formulário no Admin.

> Se você deseja desenvolver/codar uma nova seção, consulte nosso
> [Guia de desenvolvimento](https://deco.cx/docs/pt/developing-guide/setup).
Vamos selecionar a seção Hero.

Após a seleção, podemos ver o formulário onde podemos editar suas propriedades.
Essas propriedades são obtidas a partir das props do TypeScript dessa seção.

> Nota: O exemplo que você vê acima é de um bloco reutilizável, que é um recurso
> global que pode ser usado por outras páginas. Por isso, você não pode editar
> essa seção a menos que a desanexe para alterar apenas nessa página ou a edite
> em um novo espaço (o que afetará todas as páginas que a utilizam).
Vamos desanexar a seção para editar suas propriedades para essa página. Vamos
mudar o Título na propriedade Title. À medida que você faz alterações, a
pré-visualização será atualizada em tempo real para mostrar como a seção ficará
com os novos valores de propriedade.

Cada componente pode ter diferentes propriedades que podem ser personalizadas.
Essas propriedades são definidas no código da seção e podem ser acessadas
através do objeto props.
# Criando um Site
Source: https://docs.deco.cx/pt/getting-started/creating-a-site
Passo a passo de como criar um site na Deco.cx.
Esta documentação vai te guiar pelo processo de criação e configuração do seu
primeiro site usando o Deco.cx. Um site Deco é o principal ativo para os
usuários do Deco, servindo como o centro para criar, editar e gerenciar seu
próprio espaço na web.
## 1. Selecionar um Template
Vá para o [Deco Admin](https://admin.deco.cx/spaces/new) e selecione um template
para começar. Neste exemplo, vamos escolher o template de landing page, que tem
a estrutura e componentes comuns a páginas de aterrissagem.

## 2. Explorar o Template
Depois de selecionar um template, você pode explorar seus componentes em modo
compartilhado de visualização apenas. Isso permite que você explore as
configurações e recursos do template sem fazer nenhuma alteração.

## 3. Salvar Seu Site
Para criar oficialmente seu site a partir do template, clique no botão "Use this
template" no canto superior direito da página de administração para reivindicar
a propriedade do site.

### 3.1. Faça login na Plataforma
### 3.2. Dê um Nome ao Seu Site e Escolha uma Equipe
Você será solicitado a escolher um nome para o seu site e uma equipe para
salvá-lo:

Se você ainda não tiver uma equipe, uma será criada com um nome à sua escolha:

A Deco vai configurar seu site de acordo com o template que você escolheu.
## 4. Finalizar Configuração do Site
Você será redirecionado para a página inicial do site:

A partir daqui, você tem duas opções:
1. Rodar seu site localmente usando seu ambiente de desenvolvimento local.
* Isso te dá o poder de modificar seu site alterando seu código, bem como
usando o Deco Admin.
2. Criar um novo ambiente para editar seu site apenas através do Deco Admin.
* Aqui você pode fazer alterações no seu site sem precisar ter acesso ao
código do site.
### Opção 1: Rodar Seu Site Localmente
Para rodar seu site localmente, você precisa:
1. Instalar o Deno na sua máquina. Você pode seguir as instruções no
[site do Deno](https://deno.land/).
2. Clonar o repositório do site:
```bash
git clone git@github.com:deco-sites/maria-landing.git
```
3. Entrar na pasta do repositório e iniciar o servidor:
```bash
cd maria-landing
DECO_ENV_NAME=localhost deno task start
```
Agora, você pode modificar o código e ver as mudanças no Admin e vice-versa.
### Opção 2: Criar um Novo Ambiente
Ambientes são espaços de trabalho isolados onde você pode fazer alterações no
seu site sem afetar o site ao vivo. Para criar um novo ambiente:
1. Clique no botão "New" no dropdown de ambientes no Admin.

2. Escolha um nome e um host para o seu ambiente. Como não vamos rodar o site
localmente, selecione a opção Web para o host.

Agora você tem seu próprio ambiente e espaço de trabalho isolado para fazer
alterações no seu site sem precisar rodar seu código.
## (Opcional) 5. Deploy do Seu Site
Se você quiser fazer o deploy do seu site usando o Hosting da Deco, você pode
fazer isso clicando no botão "Add Deco Hosting" na página inicial do site ou no
botão "Go live" no dropdown de ambientes.
Seu site se tornará acessível através de uma URL pública como
`https://deco-sites-maria-landing.deno.dev/`.
Esse deploy incluirá 5.000 visualizações de página (compartilhadas entre todos
os sites da equipe). Se você precisar de mais visualizações de página, você pode
[atualizar seu plano](https://deco.cx/en/pricing) no Deco Admin.
## 6. Parabéns! Você Criou Seu Primeiro Site Deco
É isso aí! Agora você pode editar seu site como quiser. Não se esqueça de seguir
os próximos tutoriais para descobrir mais recursos e capacidades do Deco.cx.
# Redirecionando sem WWW
Source: https://docs.deco.cx/pt/getting-started/custom-domains/apex-domains
Como redirecionar domínio sem www
## O que é domínio apex?
Domínio apex é o termo utilizado para domínio raiz, sem subdomínio.
Exemplo:
* `www.example.com.br` -> Subdomínio
* `loja.example.com.br` -> Subdomínio
* `example.com.br` - Domínio Apex
## Posso apontar um site deco.cx para o domínio apex?
Não, ainda não é possível apontar um site deco.cx para o seu domínio apex.
Por isso, criamos uma solução fácil de redirecionamento, para que os acessos ao
domínio Apex não sejam perdidos.
## Como redirecionar um domínio apex na deco.cx?
1 - No painel do seu site na deco.cx, acesse a página de Configurações.
2 - Clique em "Adicionar domínio existente"
3 - Insira o seu domínio apex (sem subdomínio):

4 - Defina para qual subdomínio redirecionar:

5 - Agora, você verá os apontamentos que devem ser feitos na sua plataforma de
hospedagem de domínio:

6 - Após realizar as configurações, clique em Validar Domínio.
A etapa de validação é essencial para o funcionamento e ela depende da
propagação do DNS configurado no serviço de hospedagem.
No geral, a propagação ocorre dentro algumas horas, mas pode levar até 48 horas
em alguns casos.
# Configurando GTM
Source: https://docs.deco.cx/pt/getting-started/gtm
Aprenda como configurar o GTM na Deco
Adicionar o Google Tag Manager (GTM) é uma prática comum em muitos sites. A
plataforma deco.cx oferece uma section que facilita a integração automática do
GTM ao seu site. No entanto, é importante notar que o uso de um GTM com muitos
scripts pode impactar negativamente a experiência de navegação e desempenho do
site.
## Adicionando uma Section Global para Carregamento no Site
Uma boa prática é adicionar a section que carrega o script GTM em todas as
páginas do site. Isso pode ser feito utilizando sections globais, que são
carregadas automaticamente em todas as páginas geradas no admin. No caso de
páginas proxied, é necessário inserir o script diretamente na origem.
Comece selecionando o app do site:

Em seguida, localize as propriedades das sections globais:

Por fim, adicione a section de Analytics:

## Configurando sua Section
A section padrão de Analytics oferece várias opções de configuração. Se você já
tem o ID do container GTM, basta inseri-lo no campo "Tracking ID" para ativar o
uso no site. Se estiver utilizando um Measurement ID, também pode configurar
essa propriedade.
Além disso, é possível configurar fontes (sources) personalizadas para o site.

## Configurando um GTM por Página
Também existe a opção de adicionar a section de Analytics em páginas
específicas. Dessa forma, cada página pode ter seu próprio GTM, permitindo o uso
de diferentes configurações para diferentes seções do site.
# O que é deco.cx
Source: https://docs.deco.cx/pt/getting-started/overview
deco.cx é um construtor de sites que permite criar, personalizar e implantar sites com facilidade. Com foco na personalização, você pode criar experimentos, segmentar conteúdo por público-alvo e muito mais.
## A Web está quebrada, complicada e fragmentada.
Nos últimos 10 anos, nossa equipe construiu sites e aplicativos de alto volume e
missão crítica. Testamos a maioria dos novos frameworks e arquiteturas frontend,
desde KnockoutJS até React e GraphQL. Refletindo sobre nossos desafios e
resultados, acreditamos que o estado atual do desenvolvimento web está
quebrado:
🧩 A complexidade para construir e implantar um aplicativo web tem
aumentado constantemente, desencorajando desenvolvedores juniores a
construir para a web.
😓 Desenvolvedores e criadores de conteúdo frequentemente têm dificuldade em
colaborar porque o CMS Headless se torna um silo, exigindo muito tempo para
integrar e evoluir;
🐢 Aplicativos orientados para o cliente têm um desempenho terrível para
sites de alto volume, impulsionados por conteúdo, como lojas de comércio
eletrônico, que enviam quantidades cada vez maiores de código JavaScript.
Queríamos uma maneira mais simples para os desenvolvedores web construírem e
colaborarem com seus colegas de marketing, usando tecnologias web modernas e sem
precisar configurar tantas coisas. "No-code" não é suficiente e muitas vezes
retira poder dos desenvolvedores. Queríamos ter um ambiente único, desde o
código até o conteúdo e os dados. Queríamos construir o outro lado do código, um
construtor de experiências colaborativo para desenvolvedores e criadores de
conteúdo trabalharem juntos.
## Tornando o desenvolvimento web simples para equipes de todos os tamanhos
É por isso que criamos deco.cx: uma plataforma completa de desenvolvimento web
para desenvolvedores e equipes de conteúdo construírem experiências
colaborativas juntos. Os desenvolvedores escrevem componentes e funções
usando Deno, JSX, HTMX, TypeScript e Tailwind. Nós geramos automaticamente
uma bela interface de administração visual a partir do código TypeScript!
Esqueça a configuração cara e complexa de um CMS Headless, ou a estrutura
inflexível de uma prisão no-code. deco.cx oferece uma solução perfeita, tornando
o desenvolvimento web simples para equipes de todos os tamanhos:
🔧 Editor de código local ou baseado na web com visualização de conteúdo em
tempo real
📝 Conversão automática de código TypeScript para Esquemas de Conteúdo
👥 Colaboração em tempo real e histórico de lançamento baseado em Git com
rollback fácil
🤖 Decopilot, nosso assistente de IA para criação de código e conteúdo
🌍 Editor de SEO global e específico da página
🎨 Editor de Temas personalizável usando Tailwind e DaisyUI (importação com IA!)
🏢 Recursos de nível empresarial, incluindo controle total sobre ciclos de
lançamento, permissões baseadas em funções, análise web em tempo real com
Plausible e monitoramento de erros com HyperDX.
## Por que escolher deco.cx
### Do código ao conteúdo colaborativo - crie sua própria solução no-code personalizada
Lidar com editores de "tipo de conteúdo" é uma dor de cabeça. Com deco.cx, você
apenas escreve componentes React (JSX) com TypeScript e nós geramos
automaticamente um editor no-code que corresponde às suas Props.
### Pacote poderoso: análise em tempo real e observabilidade prontas para uso
Configurar sua pilha de observabilidade e análise pode ser devastador. Deco vem
com ferramentas abrangentes que permitem a qualquer pessoa verificar logs de
erros, rastreamento e métricas para ter controle total.
### Biblioteca de componentes baseada em SSR JSX + HTMX tailwind ultra leve
Escolhemos cuidadosamente uma pilha que prioriza o desempenho sem sacrificar a
simplicidade. Nossa pilha inclui tecnologias como htmx, que permite uma
comunicação perfeita e eficiente entre o cliente e o servidor.
## Comunidade, aprendizado e Get Site Done
* [Junte-se à nossa comunidade no Discord!](https://deco.cx/discord)
* [Matricule-se em nossos cursos deco.camp](https://deco.camp)
* [Get Site Done!](https://www.getsitedone.com/)
## Próximos passos!
* [Primeiros passos](https://deco.cx/docs/pt/getting-started/creating-a-site): Dê seus
primeiros passos com deco! Saiba mais sobre nosso CMS e os conceitos básicos.
* [Guia de Desenvolvimento](https://deco.cx/docs/pt/developing-guide/setup): Aprenda a
programar seu site usando nosso framework.
* [Recursos do CMS](https://deco.cx/docs/pt/cms-capabilities/home): Explore o que nosso CMS
pode fazer além do básico.
* [Recursos de Desenvolvimento](https://deco.cx/docs/pt/developing-capabilities/blocks):
Encontre referências para implementar funcionalidades avançadas em nosso
framework.
# null
Source: https://docs.deco.cx/pt/performance/edge-async-render
Documentation on async rendering in Deco.cx.
## Introdução
A renderização assíncrona é uma técnica essencial para melhorar a performance e
a experiência do usuário em aplicações web modernas. Este recurso na deco.cx
utiliza o paradigma de carregamento progressivo para carregar seções de uma
página de forma assíncrona: renderizando o conteúdo das requisições rápidas e
recorrendo a esqueletos e estados de carregamento para o conteúdo de requisições
lentas, oferecendo aos usuários uma experiência visual imediata.
## Como funciona
A renderização assíncrona na deco.cx é baseada em loaders, que são componentes
responsáveis por carregar os dados necessários para alguma seção. Os loaders
estão vinculados a um orçamento de tempo. Uma vez atingido esse limite, os
loaders que concluíram seu trabalho terão seu conteúdo renderizado no HTML final
como de costume. Os loaders que consomem APIs lentas levantarão uma exceção e um
estado de carregamento será renderizado nas seções que consomem este carregador.
Este estado de carregamento usará nosso recurso
[Partials](https://deco.cx/docs/en/developing-capabilities/interactive-sections/partial) para
hidratar e substituir a seção ausente preguiçosamente.
### Stale Edge Cache
O async render na deco.cx também conta com o recurso de "Stale Edge Cache", uma
abordagem que permite caching de seções lazy-loaded, reduzindo
significativamente os tempos de resposta e melhorando o tempo de carregamento.
Com o Stale Edge Cache, a primeira resposta do servidor da seção é armazenada em
cache no CDN. As requisições subsequentes são respondidas com essa resposta em
cache, reduzindo drasticamente o tempo total de resposta para apenas a latência
entre o navegador e o CDN, mais o tempo de download do conteúdo.

Essa funcionalidade está ativada por padrão para todas as seções, mas pode ser
desativada se necessário.
### Como ativar a renderização assíncrona
Esse recurso é ativado por padrão nas sections dos sites na deco. Para
desativar, basta desabilitar a opção `Otimization` nas propriedades da section
no Admin.

### Benefícios
* **Melhoria de Performance**: Carrega apenas os componentes necessários no
momento, reduzindo o tempo de carregamento inicial da página.
* **Redução de Latência**: Com o cache das respostas, os tempos de resposta são
significativamente reduzidos.
* **Melhor UX**: Evita o bloqueio da interface e minimiza mudanças de layout
durante o carregamento.
### Minimização de Content Layout Shifts (CLS)
Para garantir uma experiência de usuário suave, recomenda-se a implementação do
componente `LoadingFallback` em todas as seções do site. Esse componente fornece
um estado de carregamento personalizado durante o processo de renderização
assíncrona, minimizando possíveis mudanças de layout.
Você pode encontrar mais informações sobre o componente
[`LoadingFallback` em nossa documentação](https://deco.cx/docs/en/developing-capabilities/sections/loading-fallback).
## Conclusão
A renderização assíncrona é uma técnica poderosa para melhorar a performance e a
experiência do usuário em aplicações web. Com a implementação e evolução da
renderização assíncrona na plataforma deco.cx, ficou ainda mais fácil e
eficiente adotar essa técnica em seus projetos.
Para mais informações, consulte os blogposts
[Renderização Assíncrona](https://deco.cx/en/blog/async-rendering) e
[Mais sobre Renderização Assíncrona](https://deco.cx/en/blog/async-render-default).
# O guia deco para performance
Source: https://docs.deco.cx/pt/performance/guide
O guia deco para performance
## Três regras para o alto desempenho
### Entenda o framework e arquitetura do sistema
Usar uma ferramenta de forma eficiente implica em entender seus componentes e
capacidades. Isso permite ter uma base de código saudável desde o começo.
> **Exemplo**: a deco oferece componentes como `Image` que ajudam a acelerar a
> entrega de imagens de forma eficiente, mas nada impede que o usuário continue
> usando o elemento `img`.
### Aprenda a analisar o desempenho
Aprenda a analisar o desempenho das suas páginas. Navegar em uma página não deve
ser algo lento, nem mesmo para você. **Se está lento para o desenvolvedor,
estará para o usuário**. Entenda as ferramentas disponíveis e como elas
funcionam.
### Acompanhar o desempenho é uma tarefa contínua
Uma vez que o sistema para de performar, é comum deixar de se importar com este
aspecto até que se torne bem mais difícil fazer correções. A detecção de
problemas de desempenho é uma tarefa contínua, mas não deve ser um fim por si
só.
> **Importante**: o mais importante (a regra de ouro) é a experiência do
> usuário. Por vezes, o sistema pode não entregar o melhor desempenho, desde que
> isso seja uma decisão consciente para entregar a melhor experiência ao
> usuário.
## Analisando o desempenho de uma página
Testar o desempenho passa por entender uma série de ferramentas e possíveis
métricas que buscadm entender o que deve ser melhorado (e como). Existem
ferramentas que ajudam neste processo. Entenda como e quando utilizá-las.
### Testando localmente

**Sempre teste localmente a sua página, section, loader ou action. Por vezes,
não precisa ser um teste estruturado**. Se já estiver lento para você, já estará
para o usuário.
Execute as versões de teste deployadas. Em seguida, use as ferramentas
disponíveis no próprio browser para depurar problemas de desmpenho. Com elas é
possível acompanhar o desempenho da página em detalhes, e simular condições
adversas (como uma rede ou cpu de menor qualidade). Mais informações no guia
abaixo:
### Teste de pagespeed

O [pagespeed](https://pagespeed.web.dev/) é uma ferramenta de teste desenvolvida
pela google para avaliar principais aspectos de desempenho de uma página.
Explora métricas como quanto tempo até que seja exibido algum conteúdo, quanto
tempo o sistema passa a ser interagível, etc.
As principais métricas são descritas abaixo:
| Métrica | Significado | exemplo de bom valor |
| ----------- | ---------------------------------------------------------- | -------------------- |
| FCP | Tempo até a primeira exibição de conteúdo | até 1,8s |
| LCP | Tempo até a maior exibição de conteúdo | até 2,5s |
| TBT | Tempo crítico bloqueante até que o usuário possa interagir | 200ms |
| Speed Index | Índice do desempenho da página em popular conteúdo | até 3,4 |
| CLS | Índice da quantidade de mudanças de layout cumulativa | até 0,1 |
> [fonte (adaptado)](https://web.dev/articles/fcp?hl=pt-br)
A google agrega essas métricas em um índice entre 0 e 100, gerando a nota do
pagespeed.
Como é um teste executável em um ambiente em produção, ele é sujeito a
variações, no entanto, uma queda abrupta no valor do pagespeed implica em olhar
para o desempenho da página o quanto antes.
### Teste de métricas deco

Por padrão a deco oferece um conjunto de métricas que são avaliadas em uma
página. Estas métricas são especializadas especialmente para sistemas como a
deco (SSR com hidratação e com muito carregamento de dados externos).
| Métrica | Significado |
| ----------------- | --------------------------------------------------------- |
| Config LCP | Configurações de carregamento do maior conteúdo da página |
| Page HTML | Tamanho da página em bytes |
| Page Islands | Número de ilhas na páginas |
| Islands Props | Tamanho em bytes das propriedades das ilhas |
| Loaders latencies | Tempo de resposta dos loaders da página |
Cada métrica é decomposta nas partes que a compõe, permitindo identificar melhor
uma possível fonte de perda de performance. Não existe um valor ideal para cada
métrica, mas é importante entender que uma HTML grande impacta no tempo de
resposta para o usuário e em métricas como pagespeed.
Um usuário que baixa a `100 kb/s` levará `5s` para baixar uma página de
`500 kb`. Isto é especialmente impactante para usuários de dispositivos móveis
operando em redes ou situações de baixa capacidade de banda.
### Teste do Core Web Vitals

Até agora, exploramos apenas testes sintéticos, ou seja, testes que são
realizados de maneira artificial e que são apenas uma aproximação do mundo real.
São testes relevantes pois uma queda de desempenho em um teste sintético,
costuma ser refletido como uam queda de desempenho no mundo real.
O Core Web Vitals representa uma coleção de métricas extraídas a partir da
experiência real de usuários. Ela inclui métricas do pagespeed bem como outras
métricas específicas da interação real de usuários.
> Acesse através do site
> [CrUX da google](https://developer.chrome.com/docs/crux/dashboard) ou
> diretamente da App CrUX no seu site deco.
Por ser uma métrica coletada, ela só tem significado agregado. A google
categoriza os valores tipicamente mês-a-mês, por isso é mais uma métrica de
acompanhamento para diagnosticar eventuais problemas de comportamento que
passaram desapercebidos ao longo do tempo, ou que refletem a mudança de público
da página.
### Depurando problemas de performance
Se, no entanto, nenhuma das ferramentas auxiliar no processo de identificação de
um problema de desempenho, execute alguns testes manuais que podem identificar a
causa do problema:
* Se você não souber que mudança causou uma perda de performance:
* Teste versões antigas do sistema para verificar qual versão impactou no
desempenho
* Caso não esteja claro, dentro de uma versão, o que a torna lenta, elimine
parte do sistema até identificar a causa.
* Para uma página lenta, elimine algumas `sections`, até que a página volte a
ter um bom desempenho. A `section` mais recentemente apagada (ou seus
`loaders` ou `ilhas`) pode ser a causa do problema.
* Elimine dependências que tenha adicionado. Verifique se o sistema melhora
com isso.
* Atualize as suas dependências.
* Melhorias de desempenho são constantemente adicionadas ao sistema e podem
corrigir problemas que levam a lentidão.
## Melhorias de desempenhos
Após identificar um problema, seja por uma experiência negativa ou por alguns
dos testes indicarem alguma métrica com valor inadequado, é preciso atuar.
Cada teste acima indica, para cada métrica, possíveis culpados e aonde olhar.
Caso tenha identificado o culpado, siga um dos guias abaixo para implementar
melhorias relacionadas.
Observe que as situações em que você deve atuar são só exemplos de alguns casos.
### 🖼️ Imagens (jpg, png, gifs, ...)
**Quando atuar**...
* Valor alto de LCP (maior imagem demora a ser baixada / vista)
* Páginas "sambando" na tela
* Grande tamanho das imagens baixadas
**Guia**: [Otimizando imagens](https://deco.cx/docs/performance/medias/images)
> **Dica**: use os componentes deco de imagens, como `` e ``, e
> os configure corretamente, incluindo largura e altura.
### 📈 Imagens (SVG)
**Quando atuar**...
* Tamanho das páginas é grande e as páginas contem SVGs embutidos e repetidos
* Problemas no Speedindex
**Guia**: [Otimizando SVGs](https://deco.cx/docs/performance/medias/svg-sprites)
### 🖹 Fontes
**Quando atuar**...
* O texto parece "mudar de tamanho" repentinamente
* O arquivo de fonte demora a ser carregado
* Valor alto de FCP (apontando a fonte como problema)
**Guia**: [Otimizando fontes](https://deco.cx/docs/performance/medias/fonts)
> **Dica**: Use fontes padrão oferecidas pela google. Se preciso use fontes de
> pouco tamanho (dando preferência a woff/woff2).
### 📜 Scripts de terceiros
**Quando atuar**...
* O sistema demora a carregar (TBT alto)
* A tela "samba" por causa de um componente inserido por um script terceiro (CLS
alto)
* Um script de terceiro é tem um tamanho grande
**Guia**: [Otimizando scripts](https://deco.cx/docs/performance/lazy-3rd-party-scripts)
> **Dica**: Tente só usar o que for extritamente necessário ou substituir
> scripts de terceiros por versões mais leves. Se não for possível, postergue a
> execução do script para depois que a página já estiver carregado e o usuário
> estiver interagindo com ela.
### 🔄 Eficiência no carregamento de dados (loaders)
**Quando atuar**...
* O sistema indica alta latência de um loader
* A página demora a carregar inicialmente
* O tamanho das props em ilhas é grande
**Guia**: [Otimizando loaders](https://deco.cx/docs/performance/loaders)
> **Dicas**:
>
> * Use `inline loaders` para transformar dados a serem enviados a uma section
> e/ou ilha
> * Considere postergar a exibição (`Deferred`) de sections com loaders custosos
> * Altere as props do loader para diminuir a quantidade de dados carregados nos
> loaders
> * Salve os loaders que são reutilizados em diferentes páginas/sections
### 🏝️ Ilhas
**Quando atuar**...
* O sistema indica um grande número de ilhas
* A página demora a carregar inicialmente
* O tamanho das props em ilhas é grande
**Guia**: [Otimizando ilhas](https://deco.cx/docs/performance/islands)
> **Dicas**: Prefira CSS puro para evitar ilhas. Utilize `children` para passar
> um JSX para dentro de uma ilha. Reduza o máximo possível o escopo da ilha
> (ex.: prefira um botão como ilha, do que todo um `form`).
## Fontes relevantes
* [web.dev - Core Web Vitals](https://web.dev/explore/learn-core-web-vitals?hl=pt-br)
* [MDN - Web Performance](https://developer.mozilla.org/en-US/docs/Learn/Performance)
# null
Source: https://docs.deco.cx/pt/performance/islands
Enviando apenas dados necessários ao cliente
## Resumo
> Uma ilha determina um componente interativo e que será hidratado no lado do
> cliente. O servidor manda todos os dados das `props` de ilhas para fazer a
> hidratação, bem como o browser precisa de tempo para processar e renderizar
> essas ilhas.
>
> Por isso, é importante tomar alguns cuidados no uso de ilhas:
>
> 1. Reduza ao máximo a quantidade de props a ser enviada / utilizada para uma
> ilha
> 2. Torne uma ilha apenas o que for necessário, lembrando de usar o `children`
> para elementos internos que não precisam de hidratação.
## Reduzindo o tamanho do JSON de props enviado para as ilhas
Ao carregar dados de APIs externas usando [Loaders](https://deco.cx/docs/pt/concepts/loader) e
enviá-los para a [Section](https://deco.cx/docs/pt/concepts/section), é possível que o tamanho
do *payload* impacte negativamente a performance do site. O impacto ocorre tanto
no tempo inicial de carregamento como também na
[hidratação](https://blog.saeloun.com/2021/12/16/hydration/), onde a página é
"inicializada" no browser para que possa ser interativa (usar `useEffect`,
`useSignal`, etc...). É possível visualizar no tamanho do JSON final através da
aba **Performance** de uma das páginas do seu site no CMS deco.
Quando o tamanho do JSON passa de \~500kb, é provável que a UI não precise do
dado completo, mas sim alguma parte dele (ou então uma computação sobre outros
valores). Para diminuir esse tamanho e melhorar a performance da página, é
possível **filtrar os dados** ainda no Loader para que apenas o necessário seja
passado para a UI.
### Reduzindo dados enviados às ilhas
Nesse primeiro exemplo, mostraremos como evitar enviar muitos dados para uma
ilha. Digamos que existe um componente chamado ProductCard, que recebe todo o
JSON de um produto.
```tsx
import Image from "apps/website/components/Image.tsx";
export default function ProductCard({ product }: Props) {
return (
);
}
```
Nele, você deseja incluir uma
[Island](https://fresh.deno.dev/docs/concepts/islands) para criar o botão de
comprar.
```tsx
import BuyButton from "$store/components/ui";
import Image from "apps/website/components/Image.tsx";
export default function ProductCard({ product }: Props) {
return (
);
}
```
É possível que esse BuyButton, precise de algumas informações do produto para
poder adicionar ao carrinho.
Aqui que devemos tomar cuidado a quantidade de dados enviados para a Island. Por
exemplo, é bem possível que o botão de comprar não precise receber dados de
imagem.
O ideal é enviar apenas os dados necessários
> ❌ Abordagem inadequada
```tsx
import BuyButton from "$store/components/ui";
import Image from "apps/website/components/Image.tsx";
export default function ProductCard({ product }: Props) {
return (
);
}
```
> ✅ Abordagem correta
```tsx
import BuyButton from "$store/components/ui";
import Image from "apps/website/components/Image.tsx";
export default function ProductCard({ product }: Props) {
return (
);
}
```
A abordagem correta envia apenas os dados de ID e Seller, que no exemplo, são os
únicos necessários na Island.
Assim, no momento de hidratação, o JSON que a Island irá carregar não será tão
grande.
### Reduzindo o escopo de uma ilha
Uma ilha e seus componentes serão todos hidratados do lado do cliente para
poderem operar. Isto significa que, para todos os elementos definidos da ilha,
eles serão recursivamente hidratados.
É possível reduzir o escopo da ilha, fazendo com que, qualquer elemento interno,
seja passado como `children` da ilha.
> ❌ Abordagem inadequada
No exemplo abaixo, criamos uma ilha que interage com o `localStorage` para
definir um título para uma galeria de itens. No exemplo abaixo, tanto os props
de gallery serão inseridos para hidratar o `TitleContainer`, como serão também
inseridos para poder hidratar o `Gallery`.
```tsx
import { computed } from "@preact/signals";
import { IS_BROWSER } from "$fresh/runtime.ts";
import type { GalleryProps } from "../components/Gallery.tsx";
import { Gallery } from "../components/Gallery.tsx";
export default function TitleContainer(
{ galleryProps }: { galleryProps: GalleryProps },
) {
const title = computed(() => {
IS_BROWSER ? localStorage.getItem("title") : "Loading...";
});
return (
{title}
);
}
```
> ✅ Abordagem correta
Se, no entanto, o `Gallery` for repassado como children para a ilha, ele será
renderizado, serializado e não será hidratado! Para o `TitleContainer`, o
`children` é um html pronto para ser exibido, e, portanto, não é uma ilha em si.
```tsx
import { computed } from "@preact/signals";
import type { ComponentChildren } from "preact";
import { IS_BROWSER } from "$fresh/runtime.ts";
export default function TitleContainer(
{ children }: { children: ComponentChildren },
) {
const title = computed(() => {
IS_BROWSER ? localStorage.getItem("title") : "Loading...";
});
return (
{title}
{children}
);
}
```
Uso do title container (em uma section, por exemplo):
```tsx
//...
//...
```
# null
Source: https://docs.deco.cx/pt/performance/lazy-3rd-party-scripts
Aprenda como usar scripts de terceiros em seu site sem perder desempenho.
## Resumo
> O uso de scripts de terceiros pode ter um grande impacto no desempenho de um
> site. Tais scripts costumam operar de forma bloqueante e podem atrapalhar o
> tempo de carregamento das páginas.
>
> Para reduzir o tenpo gasto com tais scripts, recomenda-se:
>
> 1. Evitar ao máximo usar scripts de terceiros
> 2. Postergar o carregamento dos scripts para após a interação do sistema
> 3. Usar async ou defer nos scripts
> 4. Pré-carregar conexão com a origem do script
## Postergando o carregamento de scripts.
Caso o script em questão não seja prioritário, isto é, pode aguardar uma
interação do usuário ou não representa uma funcionalidade vital ao site, uma
recomendação é postergar seu carregamento para o momento em que o usuário
interage com o site de fato.
Cada script pode exigir uma estratégia diferente para postergar sua execução.
Abaixo, existe um exemplo de uma estratégia comum
([fonte](https://metabox.io/delay-javascript-execution-boost-page-speed/)) para
postergar o script para que seja executado apenas após a interação do usuário
seguida de um atraso:
```tsx
```
Outra alternativa é fazer uso da intersection API, de forma que o código seja
executado apenas quando um determinado elemento esteja em tela (útil para aquilo
que deve ser executado só após o usuário der scroll em uma tela).
```jsx
const elem = document.getElementById(id);
const observer = new IntersectionObserver((items) => {
// YOUR SCRIPT CONTENT
observer.unobserve(elem);
});
observer.observe(elem);
```
## Async e Defer nos script
A presença de uma tag `
```
## Próximos passos
Features que ainda não estão disponíveis, mas já estamos trabalhando para
lançar:
* Configuração de tráfego
No Teste a/b para sites deco.cx já é possível definir a quantidade de tráfego,
estamos trabalhando para implementar na SDK também.
* Testes em paralelo
No Teste a/b para sites deco.cx já é possível rodar mais de um teste ao mesmo
tempo, estamos trabalhando para implementar na SDK também.
* Testes A/B/C/...
Estamos trabalhando para implementar a possibilidade de testes com mais de duas
versões.
# null
Source: https://docs.deco.cx/pt/sdk/feature-flags
Feature Flags
## O que são Feature Flags?
É uma técnica de desenvolvimento de software que permite ativar ou desativar
funcionalidades específicas de um aplicativo sem alterar o código ou fazer um
novo deploy.
Confira as tecnologias já suportadas e suas respectivas documentações:
## React
[deco-sdk npm](https://www.npmjs.com/package/deco-sdk)
# null
Source: https://docs.deco.cx/pt/sdk/headless-cms
Aprenda como gerenciar um site ou aplicativo externo com a Deco
Na deco.cx, oferecemos a funcionalidade de criar e gerenciar sites de forma
intuitiva por meio do admin Deco. Cada página do seu site é representada por um
conjunto de dados estruturados no formato JSON, que captura todo o conteúdo
presente nessa página. Todas as alterações feitas no sistema de gerenciamento de
conteúdo (CMS) para uma página específica são imediatamente refletidas no JSON
correspondente a essa página. Esse processo de atualização em tempo real permite
que aplicativos ou sites externos à plataforma Deco acessem e incorporem essas
mudanças, possibilitando uma integração fluida entre diferentes sistemas e
ambientes, incluindo ambientes de teste (staging) e produção.
O fluxo de atualização é ilustrado no diagrama abaixo:

## Obtendo conteúdo do site Deco em site ou aplicativo externo
Para acessar o conteúdo do seu site Deco em formato JSON a partir de um site ou
aplicativo externo, você pode utilizar uma requisição GET simples à URL do site,
incluindo uma queryString `asJson`.
Por exemplo, ao acessar a página inicial do seu storefront, você verá a página
totalmente renderizada e pronta para uso, com todos os elementos visuais e
interativos:

No entanto, se você deseja acessar apenas os dados estruturados da página para
utilizá-los em um contexto diferente, como um aplicativo móvel ou uma integração
com outro sistema, basta adicionar a query string `?asJson` à URL. Isso
resultará em uma resposta JSON contendo os dados estruturados correspondentes ao
conteúdo da página, permitindo uma fácil integração e manipulação desses dados
em seu aplicativo externo:

Essa abordagem de "cabeça sem corpo" (headless) do CMS Deco oferece
flexibilidade e poder, permitindo que você reutilize o conteúdo do seu site em
uma variedade de contextos e plataformas.
# null
Source: https://docs.deco.cx/pt/self-host/architecture
Arquitetura Self-host
## Arquitetura de sites na deco.cx
A arquitetura de alto nível da deco integra diferentes papéis (Usuário, Usuário
de Negócios, Desenvolvedor), um servidor web do site, uma rede de entrega de
conteúdo (CDN), funcionalidades administrativas e sistemas externos (bancos de
dados, e-commerce, SaaS). O foco está no gerenciamento de conteúdo e ambientes
de desenvolvimento/configuração, com interação entre diversos stakeholders e
componentes.
### Visão Geral da Arquitetura
1. **Usuários:**
* **Usuário Final:** Acessa o site por meio da CDN da deco.
* **Usuário de Negócios:** Interage com o sistema pelo ambiente web para
visualizar e editar conteúdo no "Admin".
* **Desenvolvedor (Dev):** Trabalha localmente, envia alterações pelo Git e
realiza deploy via pipelines de CI/CD.
2. **Componentes do Sistema:**
* **CDN:** Entrega o site aos usuários finais.
* **Site:** O servidor web acessado pelos usuários através da CDN.
* **Ambiente Web (Web Env):** Onde desenvolvedores e usuários de negócios
visualizam alterações que estão salvas no ambiente.
* **Painel Administrativo (Admin):** Centraliza o controle das alterações,
salvando-as no Git e refletindo as alterações nos ambientes web e local.
* **Git:** Sistema de controle de versão, integrando mudanças do Admin e
desenvolvedores, com deploy via CI/CD.
* **Sistemas Externos (Banco de Dados, E-commerce, SaaS):** Integram dados e
serviços consumidos pelo site.
### Componentes e Fluxos de Processo
1. **Entrega de Conteúdo:**
* **Usuários:** Interagem com o site ao vivo pela CDN, com conteúdo otimizado
para rápida entrega.
2. **Fluxo de Trabalho do Usuário de Negócios:**
* **Visualizar/Editar:** Usuários de negócios editam conteúdo no Admin e
visualizam as mudanças no ambiente web.
* **Publicar:** As alterações são salvas no Git e propagadas ao site via
pipeline CI/CD.
3. **Fluxo de Trabalho do Desenvolvedor:**
* **Ambiente Local:** Desenvolvedores fazem mudanças locais, sincronizam com
o Admin, e enviam ao Git.
* **CI/CD:** Após o envio ao Git, as mudanças são automaticamente deployadas
via CI/CD.
## Arquitetura deco.cx com Self-host do Site
### Mudança na Arquitetura com Self-Host do Site
Com o self-host, o site passa a ser hospedado na infraestrutura da própria
organização. Veja as principais mudanças e impactos:
### Mudanças Principais
1. **Self-host do Site e Sistemas Internos:**
* O **Site** é hospedado localmente ou em infraestrutura própria, fora do
controle direto da deco.cx.
* **Sistemas Internos** (banco de dados e softwares) se integram diretamente
com o site self-hosted.
2. **Túnel para Acessar o Site:**
* Usuários e sistemas da deco.cx acessam o site self-hosted via um túnel ou
acesso público, a escolha e controle da organização.
3. **CI/CD e Git Gerenciam o Site:**
* Mesmo com o self-host, o **CI/CD** ainda é necessário para publicar as
alterações de código e conteúdo no Site, sob responsabilidade da
organização.
4. **Continuidade da Infraestrutura deco.cx:**
* O **Web Env** e o **Admin** permanecem na infraestrutura da deco.cx. Caso
seja necessário, a organização deve prover e configurar o acesso do
ambiente web aos sistemas internos via túnel (ou acesso público).
### Impacto da Mudança
* **Maior Controle:** A organização tem mais controle sobre o site e sistemas
internos.
* **Complexidade Adicional:** O túnel e CI/CD próprios aumentam a
responsabilidade de manutenção.
* **Sem Recursos deco.cx:** Não há acesso à CDN e outros serviços da deco.cx
responsáveis pela segurança e otimização do acesso ao site.
* **Customização Local:** Maior flexibilidade para acesso aos sistemas internos.
### Aspectos Relevantes da Solução Self-Host
* **Cache de Renderização Assíncrona:** Por padrão, a CDN realiza cache das
seções renderizadas na rota `/deco/render` (HTMX e partials). Sem esse cache,
o sistema pode ser sobrecarregado com requisições desnecessárias. Portanto, é
recomendável implementar o cache desses elementos na solução self-host.
* **Cache do Loader:** As chamadas aos loaders recebem cache local no servidor
web. Esse cache, por padrão, ocupa 1GB e pode consumir o espaço em disco da
imagem se não for montado com um tamanho adequado. Esta e outras opções podem
ser configuradas via variáveis de ambiente e são definidas no código do deco
runtime.
## Arquitetura deco.cx com Self-host do Site e Ambientes
### Mudança na Arquitetura com Self-Host do Site e dos Ambientes (Envs)
Com essa mudança, tanto o **Site** quanto os **Ambientes Web** são
auto-hospedados. Isso dá à organização controle total sobre desenvolvimento,
produção e integração com sistemas internos.
### Mudanças Principais
1. **Self-Host do Site e Ambientes (Envs):**
* Tanto o **Site** quanto o **Web Env** são hospedados em infraestrutura
própria.
2. **Túnel para Acessar o Ambiente Web:**
* Interação com o ambiente web auto-hospedado ocorre via túnel, mantendo
conectividade com a deco.cx. É necessária intervenção da deco.cx caso o
túnel não seja acessível publicamente.
3. **CI/CD e Git:**
* **CI/CD** gerencia as mudanças localmente, com deploy automático para o
site self-hosted, mas sob responsabilidade da organização.
4. **Continuidade da Infraestrutura deco.cx:**
* O **Admin** continua conectado à deco.cx, mas depende do túnel para
interagir com o ambiente self-hosted.
### Impacto da Mudança
* **Controle Completo:** Total controle sobre site e ambientes, oferecendo
flexibilidade.
* **Independência da deco.cx:** Menor dependência de serviços terceirizados para
desenvolvimento.
* **Complexidade de Manutenção:** Maior responsabilidade sobre segurança e
desempenho.
* **CI/CD Local:** Pipelines de CI/CD personalizados são necessários para o
deploy local.
### Conclusão
Com self-host do site e dos ambientes, a organização tem maior controle e
flexibilidade, mas assume mais responsabilidade por segurança e manutenção, além
da conectividade dos sistemas.
# null
Source: https://docs.deco.cx/pt/self-host/envs
Self-host seus envs
## Deploy de Envs (Docker)
Uma env representa um ambiente de modificação de código ou conteúdo. Ela
armazena os arquivos e suas alterações, além de se comunicar com o Git para
baixar arquivos e publicar alterações.
Para facilitar o processo de deploy, oferecemos uma estratégia Docker para
publicação de imagens.
No admin, crie uma env **local** antes de fazer o deploy e capture o nome do
ambiente (`DECO_ENV_NAME`).
## Dockerfile
Para realizar o deploy em Docker, crie e publique o Dockerfile abaixo. Não é
necessário nenhum arquivo adicional, exceto as chaves Git a serem utilizadas no
projeto.
A chave Git é necessária para que a imagem possa publicar alterações. No exemplo
abaixo, utilizaremos dois arquivos:
* `ssh/id_ed25519`: chave privada gerada
* `ssh/id_ed25519.pub`: chave pública associada à chave privada acima e ao
repositório Git
Além disso, temos variáveis que podem ser alteradas conforme sua necessidade:
* `DECO_ENV_NAME`: Nome do ambiente adicionado no admin
* `DECO_SITE_NAME`: Nome do projeto
* `DECO_REPO_URL`: Endereço de acesso via SSH ao seu repositório Git
```dockerfile
# Use the specified Docker image
FROM ghcr.io/deco-cx/deco:latest
# Set environment variables
ENV DECO_ENV_NAME=test-env \
DECO_SITE_NAME=selfhostmgr \
DECO_TRACKING_BRANCH=main \
DECO_APP_NAME=site \
DECO_REPO_URL=git@github.com:deco-sites/selfhostmgr.git
# Create .ssh directory and add GitHub known hosts
RUN mkdir -p /home/deno/.ssh && \
ssh-keyscan github.com >> /home/deno/.ssh/known_hosts
# Copy the SSH key into the container (assuming you have it locally)
# Replace "id_rsa" with the actual filename of your private key
COPY ssh/id_ed25519 /home/deno/.ssh/
COPY ssh/id_ed25519.pub /home/deno/.ssh/
USER root
RUN chmod -R 700 /home/deno/.ssh
RUN chown -R deno /home/deno/.ssh
USER deno
# Additional commands for your application (if needed)
# e.g., cloning the repository, setting up dependencies, etc.
# RUN git clone $DECO_REPO_URL /app
CMD DENO_DIR_RUN=/app/deno DENO_DIR=/daemon-deno-dir deno run -A --unstable-http jsr:@deco/deco/scripts/run --build-cmd "deno task build" -- deno run --lock=deno.lock --unstable-http --lock-write --inspect --node-modules-dir=false --allow-ffi=$DENO_DIR"npm/registry.npmjs.org/@libsql" --allow-env --allow-net --allow-sys --allow-hrtime --allow-read --allow-run --allow-write=$HOME/.cache,/tmp,/deno-dir/npm,/deno-dir/deno_esbuild,/deno-dir/deno_esbuild_tmp, --unstable --unstable-hmr --unstable-kv --unstable-cron main.ts
```
### Deploy docker
Para criar a imagem Docker com base no seu projeto, execute o seguinte comando
no diretório raiz:
* `docker build -t env_image .`
Por fim, crie e execute o container Docker:
* `docker run -p 8000:8000 --name env_container env_image`
Com isso, sua env estará rodando em um container Docker, pronto para uso.
### Considerações importante
Por padrão, o env será acessíevel publicamente no endereço oferecido no admin.
Caso tenha considerações de privacidade, será preciso criar um túnel entre a env
e o repositório.
# null
Source: https://docs.deco.cx/pt/self-host/site
Self-host seu site deco
## Deploy do site (Docker)
O estado e a configuração do sistema são totalmente definidos no sistema de
arquivos. Assim, o estado do site é auto-contido no próprio sistema de arquivos,
sem a necessidade de comunicação com sistemas externos por padrão. No entanto, o
site pode acessar bancos de dados, serviços SaaS ou outros serviços web,
conforme o código implementado pelo desenvolvedor, mas isso não é um requisito
obrigatório do runtime da Deco.
Para facilitar o processo de deploy, oferecemos uma estratégia simples
utilizando um Dockerfile.
## Dockerfile
Para realizar o deploy em Docker, copie o código abaixo para um arquivo
Dockerfile na raiz do seu projeto. É necessário configurar, no mínimo, a
variável de ambiente `ENV DECO_SITE_NAME` para refletir o nome do seu site ou
projeto.
```dockerfile
FROM denoland/deno:alpine
# The port that your application listens to.
EXPOSE 8000
WORKDIR /app
RUN mkdir -p /home/deno && chown -R deno:deno /home/deno && mkdir /app/deno && chown -R deno:deno /app && mkdir -p /deno-dir && chown -R deno:deno /deno-dir
# Prefer not to run as root.
USER deno
# These steps will be re-run upon each file change in your working directory:
COPY --chown=deno:deno . deco
WORKDIR /app/deco
RUN echo -e 'import "$fresh/src/build/deps.ts";\nimport "$fresh/src/runtime/entrypoints/main.ts";\nimport "$fresh/src/runtime/entrypoints/deserializer.ts";\nimport "$fresh/src/runtime/entrypoints/signals.ts";' >> _docker_deps.ts
RUN deno cache --allow-import --frozen main.ts dev.ts _docker_deps.ts
ARG GIT_REVISION=1
ENV DECO_SITE_NAME=yoursitename
ENV DENO_DEPLOYMENT_ID=$GIT_REVISION
CMD ["run", "--cached-only", "-A", "--unstable-kv", "main.ts"]
```
### Explicação do Dockerfile
Aqui estão alguns detalhes importantes sobre o `Dockerfile` acima, que podem
precisar de personalização conforme o seu caso de uso:
* `FROM denoland/deno:alpine`
* Define a imagem base do Docker. Você pode especificar uma versão exata, como
`FROM denoland/deno:2.0.1.`
* `EXPOSE 8000`
* Expõe a porta onde a aplicação estará disponível.
* `RUN echo -e ... >> _docker_deps.ts`
* Define as dependências que serão cacheadas para evitar a busca por pacotes
externos durante a execução.
* `RUN deno cache --allow-import --frozen main.ts dev.ts _docker_deps.ts`
* Realiza o cache das dependências do projeto.
* `ARG GIT_REVISION=1`
* Permite definir um argumento de build para identificar revisões do projeto.
* `ENV DECO_SITE_NAME=yoursitename`
* Define uma variável de ambiente usada para identificar o site no runtime
Deco.
* `ENV DENO_DEPLOYMENT_ID=$GIT_REVISION`
* Variável usada para gerenciar o cache dos assets do site, devendo ser
alterada a cada novo build.
* `CMD ["run", "--cached-only", "-A", "--unstable-kv", "main.ts"]`
* Comando que executa o servidor com as permissões necessárias.
### Deploy docker
Para criar a imagem Docker com base no seu projeto, execute o seguinte comando
no diretório raiz:
* `docker build -t site_image .`
Se necessário, você pode passar o argumento `GIT_REVISION` para identificar uma
revisão específica do build:
* `docker build --build-arg GIT_REVISION=2 -t site_image .`
Finalmente, crie e execute o container Docker:
* `docker run -p 8000:8000 --name site_container site_image`
Com isso, seu site estará rodando em um container Docker, pronto para uso.