Documentación

Dicas de Dev (Playbook)

🚀 Playbook: Dicas de Dev

Acompanhe as últimas sacadas e truques para construir seu SaaS. Conteúdo fresco, focado em performance e produtividade para o ecossistema brasileiro.


2025-09-04

Gerenciamento de Estado Global com Zustand: Simples, Rápido e Sem Boilerplate

#react #next.js #typescript

No React, a Context API e o useState funcionam, mas muitas vezes levam ao "prop drilling" e re-renders desnecessários. Para SaaS escaláveis, precisamos de algo mais ágil.

Conheça o Zustand: uma biblioteca de estado ultra-leve (~3 kB), baseada em hooks, que é rápida, escalável e extremamente simples de implementar.

import { create } from 'zustand';

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}));

function Counter() {
  const { count, increment } = useStore((state) => ({
    count: state.count,
    increment: state.increment,
  }));
  return <button onClick={increment}>Clicou {count} vezes</button>;
}

Por que o Zustand brilha no nosso stack:

  • Sem Providers: O store é um hook que você usa em qualquer lugar.
  • Inscrições Seletivas: Componentes só renderizam quando a fatia de estado selecionada muda.
  • Zero Boilerplate: Sem action creators, reducers ou fábricas de contexto complexas.

Use Zustand sempre que precisar de estado global compartilhado com performance máxima e sem dor de cabeça.

Visite zustand-demo.pmnd.rs


2025-09-03

Nuqs: Estado Sincronizado com a URL (Type-Safe)

#react #next.js #typescript

Armazenar o estado dos componentes na URL torna a página compartilhável e o estado persistente no "Back" do navegador. Mas manipular searchParams manualmente pode ser um pesadelo.

O nuqs resolve isso: um hook minúsculo que funciona como useState, mas sincroniza tudo com a URL de forma 100% tipada.

import { parseAsInteger, useQueryState } from 'nuqs';

function Counter() {
  const [count, setCount] = useQueryState(
    'count',
    parseAsInteger.withDefault(0)
  );
  return (
    <button onClick={() => setCount(c => c + 1)}>Contador: {count}</button>
  );
}

Vantagens para o seu SaaS:

  • Parsing Tipado: Converte query strings em números, booleanos, datas e enums automaticamente.
  • Atualizações Otimizadas: Faz o push/replace na URL sem travar o histórico do navegador.
  • Suporte SSR Nativo: Perfeito para filtros de busca e dashboards que precisam ser indexados ou compartilhados.

Use nuqs quando quiser que o estado da sua aplicação seja compartilhável via link de forma elegante e segura.

Saiba mais em nuqs.47ng.com


2025-09-02

Extração de Dados Estruturados com AI SDK e generateObject

#ai #typescript

LLMs costumam retornar texto livre, o que é difícil de processar programaticamente. Com o AI SDK (Vercel), você pode usar generateObject para forçar um schema JSON tipado — sem regex ou gambiarras.

import { openai } from '@ai-sdk/openai';
import { generateObject } from 'ai';
import { z } from 'zod';

const result = await generateObject({
  model: openai('gpt-4o'), // Ou o modelo de sua preferência
  schema: z.object({
    nome: z.string(),
    idade: z.number(),
  }), 
  prompt: "Extraia o nome e idade: João tem 42 anos.",
});

console.log(result.object);
// → { nome: "João", idade: 42 }

Por que usar:

  • Strict Structure: Garante o formato via Zod.
  • Sem Pós-processamento: O dado já vem pronto para o seu banco de dados.
  • Segurança de Tipos: Integração total com TypeScript.

Ideal para parsear leads, extrair informações de documentos ou qualquer funcionalidade de IA no seu SaaS que precise de precisão.

Documentação do AI SDK


2025-09-01

Utilitário size- do Tailwind: Código mais limpo

#tailwindcss #css #frontend

Sempre que você quer um elemento quadrado no Tailwind, acaba escrevendo largura e altura separadamente: <div className="w-16 h-16 bg-orange-500"></div>

O Tailwind agora tem o atalho size-: <div className="size-16 bg-orange-500"></div>

Isso define width e height simultaneamente. Perfeito para avatars, ícones e containers quadrados. Menos classes, mais legibilidade.


2025-08-29

Permissões Type-Safe com Permix

#typescript #auth #frontend

O Permix é uma biblioteca leve para gerenciar permissões no seu SaaS de forma segura. Evite erros de digitação e nomes inconsistentes em permissões complexas.

import { createPermix } from 'permix'

const permix = createPermix<{
  post: { action: 'read' | 'write' }
}>()

permix.setup({
  post: { read: true, write: false }
})

const podeLer = permix.check('post', 'read') // true

Diferenciais:

  • Zero Dependências: Ultra leve.
  • Single Source of Truth: Centralize as regras de acesso do usuário.
  • Agnóstico: Funciona com React, Node, Next.js, etc.

Conheça o Permix


2025-08-28

Top Loader Bar Automática no Next.js

#next.js #ux

Adicionar uma barra de progresso no topo durante a navegação melhora muito a percepção de velocidade do seu SaaS. O pacote @bprogress/next facilita isso no App Router.

Instalação e Uso:

  1. npm install @bprogress/next
  2. Envolva seu layout.tsx com o ProgressProvider.

Isso remove a sensação de "site travado" enquanto o Next.js carrega a próxima página no servidor.


2025-08-27

Prefetching no Servidor com TanStack Query

#next.js #tanstack #ssr

Cansado de spinners de carregamento? No Next.js, você pode fazer o "prefetch" dos dados no servidor e entregar a página pronta, sem estados de loading para o usuário.

const queryClient = new QueryClient();
await queryClient.prefetchQuery({
  queryKey: ['todos'],
  queryFn: fetchTodos,
});
const dehydratedState = dehydrate(queryClient);

return (
  <HydrationBoundary state={dehydratedState}>
    <TodosList />
  </HydrationBoundary>
);

O componente cliente usará o hook useQuery normalmente, mas os dados já estarão lá. Experiência de uso instantânea (Instant Navigation).


2025-08-26

CMS Git-Based com Content-Collections e MDX

#cms #marketing #blog

Esqueça CMS externos pesados. Gerencie seu blog, docs e páginas de marketing diretamente no seu repositório Git usando Content-Collections.

Você define o schema via Zod, escreve em Markdown/MDX e acessa os dados com tipagem automática no código. É o fluxo que usamos no Novo Ofício para manter tudo rápido e versionado.

www.content-collections.dev


2025-08-25

Container Queries: Responsividade Inteligente

#tailwindcss #responsive #design

Breakpoints globais (sm:, md:) as vezes não são suficientes. Com Container Queries, o componente se adapta ao tamanho do seu pai, não da tela inteira.

<div className="@container">
    <div className="@md:text-xl @lg:text-2xl">
        Eu me ajusto conforme o tamanho do meu container pai!
    </div>
</div>

Essencial para dashboards onde o mesmo card pode aparecer em uma barra lateral estreita ou em um conteúdo principal largo.


2025-08-21

Atributo autocomplete para Melhorar a Conversão

#html #ux

Otimize seus formulários de checkout e login usando autocomplete="email", autocomplete="tel", etc. Isso reduz a fricção, ajuda o preenchimento automático do navegador e aumenta sua taxa de conversão em SaaS de pagamentos.


2025-08-19

Ganhe Performance Troca o Lodash pelo es-toolkit

#performance #typescript

O es-toolkit é uma alternativa moderna e ultra-veloz ao Lodash. Chega a ser 97% menor em bundle size e até 11x mais rápido em algumas funções. Migração direta: troque import { pick } from 'lodash' por import { pick } from 'es-toolkit'.


2025-08-17

skipToken para Consultas de Tipo Seguro

#tanstack #typescript

Em vez de usar enabled: !!id, use o skipToken do TanStack Query. Ele informa ao TypeScript de forma elegante que a consulta deve ser pulada, mantendo a tipagem correta dentro da sua queryFn.


2025-08-15

Gere Paletas de Cores Profissionais com UI Colors

#design #tailwind

Não chute as cores do seu SaaS. Use o UI Colors para gerar tons consistentes com acessibilidade e contraste garantidos. É a ferramenta que recomendamos para customizar o branding deste template.