Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

De Next.js a React Edge com Cloudflare Workers: Uma História de Libertação

A Gota D'água A Alternativa com Cloudflare 😍 React Edge: O Framework React derivado de todas (ou quase) as dores de um desenvolvedor A Magia do RPC Tipado O Poder do useFetch: Onde a Mágica Acontece Além do useFetch: O arsenal com…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

  • A Gota D'água

  • A Alternativa com Cloudflare 😍


  • React Edge: O Framework React derivado de todas (ou quase) as dores de um desenvolvedor


    • A Magia do RPC Tipado

    • O Poder do useFetch: Onde a Mágica Acontece








  • Além do useFetch: O arsenal completo


    • RPC: A Arte da Comunicação Cliente-Servidor

    • Um Sistema de i18n que Faz Sentido

    • Autenticação JWT que "Simplesmente Funciona"

    • O Store Compartilhado

    • Roteamento Elegante

    • Cache Distribuído com Edge Cache






  • Link: O Componente que Pensa à Frente


  • app.useContext: O Portal para o Edge


  • app.useUrlState: Estado Sincronizado com a URL


  • app.useStorageState: Estado Persistente


  • app.useDebounce: Controle de Frequência


  • app.useDistinct: Estado sem Duplicatas


  • A CLI do React Edge: Potência na Ponta dos Dedos


  • Conclusão







A Gota D'água



Tudo começou com uma fatura da Vercel. Não, na verdade começou bem antes - com pequenas frustrações que foram se acumulando. A necessidade de pagar por features básicas como proteção DDoS, logs mais detalhados, ou mesmo um firewall decente, filas de builds, etc. A sensação de estar preso em um vendor lock-in cada vez mais caro.




"E o pior de tudo: nossos preciosos cabeçalhos de SEO simplesmente deixaram de ser renderizados no servidor em uma aplicação utilizando o pages router. Uma verdadeira dor de cabeça para qualquer dev! 😭"




Mas o que realmente me fez repensar tudo foi a direção que o Next.js estava tomando. A introdução do use client, use server - diretivas que, em teoria, deveriam simplificar o desenvolvimento, mas na prática adicionavam mais uma camada de complexidade para gerenciar. Era como se estivéssemos voltando aos tempos do PHP, marcando arquivos com diretivas para dizer onde eles deveriam rodar.



E não para por aí. O App Router, uma ideia interessante, mas implementada de forma que criou um framework praticamente novo dentro do Next.js. De repente, tínhamos duas formas completamente diferentes de fazer a mesma coisa. A 'velha' e a 'nova' - com comportamentos sutilmente diferentes e armadilhas escondidas.






A Alternativa com Cloudflare 😍



Foi quando percebi: por que não aproveitar a incrível infraestrutura da Cloudflare com Workers rodando no edge, R2 para storage, KV para dados distribuídos... Além, é claro, a incrível proteção DDoS, CDN global, firewall, regras par páginas e rotas e tudo mais que a Cloudflare oferece.



E o melhor: um modelo de preço justo, onde você paga pelo que usa, sem surpresas.



Assim nasceu o React Edge. Um framework que não tenta reinventar a roda, mas sim proporcionar uma experiência de desenvolvimento verdadeiramente simples e moderna.






React Edge: O Framework React derivado de todas (ou quase) as dores de um desenvolvedor



Quando comecei a desenvolver o React Edge, tinha um objetivo claro: criar um framework que fizesse sentido. Não mais lutar com diretivas confusas, não mais pagar fortunas por recursos básicos, e principalmente, não mais ter que lidar com a complexidade artificial criada pela separação cliente/servidor. Eu queria velocidade, algo que entregasse performance sem sacrificar simplicidade. Aproveitando meu conhecimento da API do React e anos como desenvolvedor Javascript e Golang, sabia exatamente como lidar com streams e multiplexação para otimizar a renderização e o gerenciamento de dados.



O Cloudflare Workers, com sua infraestrutura poderosa e presença global, me ofereceu o ambiente perfeito para explorar essas possibilidades. Queria algo que fosse verdadeiramente híbrido, e essa combinação de ferramentas e experiência foi o que deu vida ao React Edge: um framework que resolve problemas reais com soluções modernas e eficientes.



O React Edge traz uma abordagem revolucionária para desenvolvimento React. Imagine poder escrever uma classe no servidor e chamá-la diretamente do cliente, com tipagem completa e zero configuração. Imagine um sistema de cache distribuído que "simplesmente funciona", permitindo invalidação por tags ou prefixos. Imagine poder compartilhar estado entre servidor e cliente de forma transparente e segura. Além de simplificar a autenticação e trazer uma abordagem de internacionalização eficiente, CLI e muito mais.



Sua comunicação RPC é tão natural que parece mágica - você escreve métodos em uma classe e os chama do cliente como se fossem locais. O sistema de multiplexação inteligente garante que, mesmo que múltiplos componentes façam a mesma chamada, apenas uma requisição seja feita ao servidor. O cache efêmero evita requisições repetidas desnecessárias, e tudo isso funciona tanto no servidor quanto no cliente.



Um dos pontos mais poderosos é o hook app.useFetch, que unifica a experiência de data fetching. No servidor, ele pré-carrega os dados durante o SSR; no cliente, ele hidrata automaticamente com esses dados e permite atualizações sob demanda. E com suporte a polling automático e reatividade baseada em dependências, criar interfaces dinâmicas nunca foi tão fácil.



Mas não para por aí. O framework oferece um sistema de rotas poderoso (inspirado no fantástico Hono), gerenciamento de assets integrado com Cloudflare R2, e uma forma elegante de lidar com erros através da classe HttpError. Os middlewares podem facilmente enviar dados para o cliente através de um store compartilhado, e tudo é ofuscado automaticamente para segurança.



O mais impressionante? Quase todo o código do framework é híbrido. Não há uma versão 'cliente' e outra 'servidor' - o mesmo código funciona nos dois ambientes, adaptando-se automaticamente ao contexto. O cliente recebe apenas o que precisa, tornando o bundle final extremamente otimizado.



E a cereja do bolo: tudo isso roda na infraestrutura edge do Cloudflare Workers, proporcionando performance excepcional a um custo justo. Sem surpresas na fatura, sem recursos básicos escondidos atrás de planos enterprise forçados, apenas um framework sólido que permite você focar no que realmente importa: criar aplicações incríveis. Além disso, o React Edge aproveita todo o ecossistema da Cloudflare, incluindo Queues, Durable Objects, KV Storage, e muito mais para oferecer uma base robusta e escalável para suas aplicações.



O Vite foi usado como base, tanto para o ambiente de desenvolvimento quanto para testes e build. O Vite, com sua velocidade impressionante e arquitetura moderna, permite um fluxo de trabalho ágil e eficiente. Ele não apenas acelera o desenvolvimento, mas também otimiza o processo de build, garantindo que o código seja compilado de forma rápida e precisa. Sem dúvida, o Vite foi a escolha perfeita para o React Edge.






Repensando o Desenvolvimento React para a era do Edge Computing



Você já se perguntou como seria desenvolver aplicações React sem se preocupar com a barreira cliente/servidor? Sem precisar decorar dezenas de diretivas como use client ou use server? E melhor ainda: e se você pudesse chamar funções do servidor como se fossem locais, com tipagem completa e zero configuração?






Com o React Edge, você não precisa:




  • Criar rotas de API separadas

  • Gerenciar estado de loading/error manualmente

  • Implementar debounce na mão

  • Se preocupar com serialização/deserialização

  • Lidar com CORS

  • Gerenciar tipagem entre cliente/servidor

  • Lidar com regras de autenticação manualmente

  • Gerenciar como a internacionalização é feita



E o melhor: tudo isso funciona tanto no servidor quanto no cliente, sem precisar marcar nada com use client ou use server. O framework sabe o que fazer baseado no contexto. Vamos lá?






A Magia do RPC Tipado



Imagine poder fazer isso:




// No servidor
class UserAPI extends Rpc {
async searchUsers(query: string, filters: UserFilters) {
// Validação com Zod
const validated = searchSchema.parse({ query, filters });
return this.db.users.search(validated);
}
}

// No cliente
const UserSearch = () => {
const { rpc } = app.useContext<App.Context>();

// TypeScript sabe exatamente o que searchUsers aceita e retorna!
const { data, loading, error, fetch: retry } = app.useFetch(
async (ctx) => ctx.rpc.searchUsers('John', { age: '>18' })
);
};









Compare isso com o Next.js/Vercel:






// pages/api/search.ts
export default async handler = (req, res) => {
// Configurar CORS
// Validar request
// Tratar erros
// Serializar resposta
// ...100 linhas depois...
}

// app/search/page.tsx
'use client';
import { useEffect, useState } from 'react';

export default const SearchPage = () => {
const [search, setSearch] = useState('');
const [filters, setFilters] = useState({});
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);

useEffect(() => {
let timeout;
const doSearch = async () => {
setLoading(true);
try {
const res = await fetch('/api/search?' + new URLSearchParams({
q: search,
...filters
}));
if (!res.ok) throw new Error('Search failed');
setData(await res.json());
} catch (err) {
console.error(err);
} finally {
setLoading(false);
}
};

timeout = setTimeout(doSearch, 300);
return () => clearTimeout(timeout);
}, [search, filters]);

// ... resto do componente
}









O Poder do useFetch: Onde a Mágica Acontece






Data Fetching Repensado



Esqueça tudo que você sabe sobre data fetching no React. O app.useFetch do React Edge traz uma abordagem completamente nova e poderosa. Imagine um hook que:




  • Pré-carrega dados no servidor durante SSR

  • Hidrata automaticamente no cliente sem flicker

  • Mantém tipagem completa entre cliente e servidor

  • Suporta reatividade com debounce inteligente

  • Multiplexa chamadas idênticas automaticamente

  • Permite atualizações programáticas e polling



Vamos ver isso em ação:




// Primeiro, definimos nossa API no servidor
class PropertiesAPI extends Rpc {
async searchProperties(filters: PropertyFilters) {
const results = await this.db.properties.search(filters);
// Cache automático por 5 minutos
return this.createResponse(results, {
cache: { ttl: 300, tags: ['properties'] }
});
}

async getPropertyDetails(ids: string[]) {
return Promise.all(
ids.map(id => this.db.properties.findById(id))
);
}
}

// Agora, no cliente, a mágica acontece
const PropertySearch = () => {
const [filters, setFilters] = useState<PropertyFilters>({
price: { min: 100000, max: 500000 },
bedrooms: 2
});

// Busca reativa com debounce inteligente
const {
data: searchResults,
loading: searchLoading,
error: searchError
} = app.useFetch(
async (ctx) => ctx.rpc.searchProperties(filters),
{
// Quando filters muda, refaz a busca
deps: [filters],
// Mas espera 300ms de 'silêncio' antes de buscar
depsDebounce: {
filters: 300
}
}
);

// Agora, vamos buscar os detalhes das propriedades encontradas
const {
data: propertyDetails,
loading: detailsLoading,
fetch: refreshDetails
} = app.useFetch(
async (ctx) => {
if (!searchResults?.length) return null;

// Isso parece fazer múltiplas chamadas, mas...
return ctx.rpc.batch([
// Na verdade, tudo é multiplexado em uma única requisição!
...searchResults.map(result =>
ctx.rpc.getPropertyDetails(result.id)
)
]);
},
{
// Atualiza sempre que searchResults mudar
deps: [searchResults]
}
);

// Interface bonita e responsiva
return (
<div>
<FiltersPanel
value={filters}
onChange={setFilters}
disabled={searchLoading}
/>

{searchError && (
<Alert status='error'>
Erro na busca: {searchError.message}
</Alert>
)}

<PropertyGrid
items={propertyDetails || []}
loading={detailsLoading}
onRefresh={() => refreshDetails()}
/>
</div>
);
};









A Mágica da Multiplexação



O exemplo acima esconde uma característica poderosa: a multiplexação inteligente. Quando você usa ctx.rpc.batch, o React Edge não apenas agrupa as chamadas - ele deduplicar chamadas idênticas automaticamente:




const PropertyListingPage = () => {
const { data } = app.useFetch(async (ctx) => {
// Mesmo que você faça 100 chamadas idênticas...
return ctx.rpc.batch([
ctx.rpc.getProperty('123'),
ctx.rpc.getProperty('123'), // mesma chamada
ctx.rpc.getProperty('456'),
ctx.rpc.getProperty('456'), // mesma chamada
]);
});

// Mas na realidade:
// 1. O batch agrupa todas as chamadas em UMA única requisição HTTP
// 2. Chamadas idênticas são deduplicas automaticamente
// 3. O resultado é distribuído corretamente para cada posição do array
// 4. A tipagem é mantida para cada resultado individual!


// Entao..
// 1. getProperty('123')
// 2. getProperty('456')
// E os resultados são distribuídos para todos os chamadores!
};









SSR + Hidratação Perfeita



Uma das partes mais impressionantes é como o useFetch lida com SSR:




const ProductPage = ({ productId }: Props) => {
const { data, loaded, loading, error } = app.useFetch(
async (ctx) => ctx.rpc.getProduct(productId),
{
// Controle fino de quando executar
shouldFetch: ({ worker, loaded }) => {
// No worker (SSR): sempre busca
if (worker) return true;
// No cliente: só busca se não tiver dados
return !loaded;
}
}
);

// No servidor:
// 1. useFetch faz a chamada RPC
// 2. Dados são serializados e enviados ao cliente
// 3. Componente renderiza com os dados

// No cliente:
// 1. Componente hidrata com os dados do servidor
// 2. Não faz nova chamada (shouldFetch retorna false)
// 3. Se necessário, pode refazer a chamada com data.fetch()

return (
<Suspense fallback={<ProductSkeleton />}>
<ProductView
product={data}
loading={loading}
error={error}
/>
</Suspense>
);
};









Além do useFetch: O arsenal completo






RPC: A Arte da Comunicação Cliente-Servidor






Segurança e Encapsulamento



O sistema RPC do React Edge foi projetado pensando em segurança e encapsulamento. Nem tudo que está em uma classe RPC é automaticamente exposto ao cliente:




class PaymentsAPI extends Rpc {
// Propriedades nunca são expostas
private stripe = new Stripe(process.env.STRIPE_KEY);

// Métodos começando com $ são privados
private async $validateCard(card: CardInfo) {
return await this.stripe.cards.validate(card);
}

// Métodos começando com _ também são privados
private async _processPayment(amount: number) {
return await this.stripe.charges.create({ amount });
}

// Este método é público e acessível via RPC
async createPayment(orderData: OrderData) {
// Validação interna usando método privado
const validCard = await this.$validateCard(orderData.card);
if (!validCard) {
throw new HttpError(400, 'Invalid card');
}

// Processamento usando outro método privado
const payment = await this._processPayment(orderData.amount);
return payment;
}
}

// No cliente:
const PaymentForm = () => {
const { rpc } = app.useContext<App.Context>();

// ✅ Isso funciona
const handleSubmit = () => rpc.createPayment(data);

// ❌ Isso não é possível - métodos privados não são expostos
const invalid1 = () => rpc.$validateCard(data);
const invalid2 = () => rpc._processPayment(100);

// ❌ Isso também não funciona - propriedades não são expostas
const invalid3 = () => rpc.stripe;
};









Hierarquia de APIs RPC



Uma das características mais poderosas do RPC é a capacidade de organizar APIs em hierarquias:




// APIs aninhadas para melhor organização
class UsersAPI extends Rpc {
// Subclasse para gerenciar preferences
preferences = new UserPreferencesAPI();
// Subclasse para gerenciar notificações
notifications = new UserNotificationsAPI();

async getProfile(id: string) {
return this.db.users.findById(id);
}
}

class UserPreferencesAPI extends Rpc {
async getTheme(userId: string) {
return this.db.preferences.getTheme(userId);
}

async setTheme(userId: string, theme: Theme) {
return this.db.preferences.setTheme(userId, theme);
}
}

class UserNotificationsAPI extends Rpc {
// Métodos privados continuam privados
private async $sendPush(userId: string, message: string) {
await this.pushService.send(userId, message);
}

async getSettings(userId: string) {
return this.db.notifications.getSettings(userId);
}

async notify(userId: string, notification: Notification) {
const settings = await this.getSettings(userId);
if (settings.pushEnabled) {
await this.$sendPush(userId, notification.message);
}
}
}

// No cliente:
const UserProfile = () => {
const { rpc } = app.useContext<App.Context>();

const { data: profile } = app.useFetch(
async (ctx) => {
// Chamadas aninhadas são totalmente tipadas
const [user, theme, notificationSettings] = await ctx.rpc.batch([
// Método da classe principal
ctx.rpc.getProfile('123'),
// Método da subclasse de preferências
ctx.rpc.preferences.getTheme('123'),
// Método da subclasse de notificações
ctx.rpc.notifications.getSettings('123')
]);

return { user, theme, notificationSettings };
}
);

// ❌ Métodos privados continuam inacessíveis
const invalid = () => rpc.notifications.$sendPush('123', 'hello');
};









Benefícios da Hierarquia



Organizar APIs em hierarquias traz vários benefícios:




  • Organização Lógica: Agrupe funcionalidades relacionadas de forma intuitiva

  • Namespace Natural: Evite conflitos de nomes com caminhos claros (users.preferences.getTheme)

  • Encapsulamento: Mantenha métodos auxiliares privados em cada nível

  • Manutenibilidade: Cada subclasse pode ser mantida e testada independentemente

  • Tipagem Completa: O TypeScript entende toda a hierarquia



O sistema de RPC do React Edge torna a comunicação cliente-servidor tão natural que você quase esquece que está fazendo chamadas remotas. E com a capacidade de organizar APIs em hierarquias, você pode criar estruturas complexas mantendo o código organizado e seguro.






Um Sistema de i18n que Faz Sentido



O React Edge traz um sistema de internacionalização elegante e flexível, que suporta interpolação de variáveis e formatação complexa sem bibliotecas pesadas.




// translations/fr.ts
export default {
'Good Morning, {name}!': 'Bonjour, {name}!',
};






Uso no código:




const WelcomeMessage = () => {
const userName = 'João';

return (
<div>
{/* Output: Bem vindo, João! */}
<h1>{__('Good Morning, {name}!', { name: userName })}</h1>
);
};









Configuração Zero



O React Edge detecta e carrega suas traduções automaticamente, podendo salvar fácilmente nos cookies a preferência do usuário. Mas isso você já esperava, certo?




// worker.ts
const handler = {
fetch: async (request: Request, env: types.Worker.Env, context: ExecutionContext) => {
const url = new URL(request.url);

const lang = (() => {
const lang =
url.searchParams.get('lang') || worker.cookies.get(request.headers, 'lang') || request.headers.get('accept-language') || '';

if (!lang || !i18n[lang]) {
return 'en-us';
}

return lang;
})();

const worker = new AppWorkerEntry({
i18n: {
en: await import('./translations/en'),
pt: await import('./translations/pt'),
es: await import('./translations/es')
}
});

const res = await workerApp.fetch();

if (url.searchParams.has('lang')) {
return new Response(res.body, {
headers: worker.cookies.set(res.headers, 'lang', lang)
});
}

return res;
}
};









Autenticação JWT que "Simplesmente Funciona"



A autenticação sempre foi um ponto de dor em aplicações web. Gerenciar tokens JWT, cookies seguros, revalidação - tudo isso geralmente requer muito código boilerplate. O React Edge muda isso completamente.



Veja como é simples implementar um sistema completo de autenticação:




class SessionAPI extends Rpc {
private auth = new AuthJwt({
// Cookie será automaticamente gerenciado
cookie: 'token',
// Payload é automaticamente encriptado
encrypt: true,
// Expiração automática
expires: { days: 1 },
secret: process.env.JWT_SECRET
});

async signin(credentials: {
email: string;
password: string
}) {
// Validação com Zod
const validated = loginSchema.parse(credentials);
const { headers } = await this.auth.sign(validated));

// Retorna resposta com cookies configurados
return this.createResponse(
{ email: validated.email },
{
headers: (await this.auth.sign(validated))
}
);
}

async getSession(revalidate = false) {
// Validação e revalidação automática de token
const { headers, payload } = await this.auth.authenticate(
this.request.headers,
revalidate
);

return this.createResponse(payload, { headers });
}

async signout() {
// Limpa cookies automaticamente
const { headers } = await this.auth.destroy();
return this.createResponse(null, { headers });
}
}









Uso no Cliente: Zero Configuração






const LoginForm = () => {
const { rpc } = app.useContext<App.Context>();

const login = async (values) => {
const session = await rpc.signin(values);
// Pronto! Cookies já estão setados automaticamente
};

return <Form onSubmit={login}>...</Form>;
};

const NavBar = () => {
const { rpc } = app.useContext<App.Context>();

const logout = async () => {
await rpc.signout();
// Cookies já foram limpos automaticamente
};

return <button onClick={logout}>Sair</button>;
};









Por Que Isso é Revolucionário?





  1. Zero Boilerplate




    • Sem gerenciamento manual de cookies

    • Sem necessidade de interceptors

    • Sem refresh tokens manual




  2. Segurança por Padrão




    • Tokens são automaticamente encriptados

    • Cookies são seguros e httpOnly

    • Revalidação automática




  3. Tipagem Completa




    • Payload do JWT é tipado

    • Validação com Zod integrada

    • Erros de autenticação tipados



  4. Integração Perfeita





// Middleware que protege rotas
const authMiddleware: App.Middleware = async (ctx) => {
const session = await ctx.rpc.session.getSession();

if (!session) {
throw new HttpError(401, 'Unauthorized');
}

// Disponibiliza sessão para componentes
ctx.store.set('session', session, 'public');
};

// Uso em rotas
const router: App.Router = {
routes: [
routerBuilder.routeGroup({
path: '/dashboard',
middlewares: [authMiddleware],
routes: [/*...*/]
})
]
};









O Store Compartilhado



Uma das features mais poderosas do React Edge é sua capacidade de compartilhar estado entre worker e cliente de forma segura. Vamos ver como isso funciona:




// middleware/auth.ts
const authMiddleware: App.Middleware = async (ctx) => {
const token = ctx.request.headers.get('authorization');

if (!token) {
throw new HttpError(401, 'Unauthorized');
}

const user = await validateToken(token);

// Dados públicos - automaticamente compartilhados com o cliente
ctx.store.set('user', {
id: user.id,
name: user.name,
role: user.role
}, 'public');

// Dados privados - permanecem apenas no worker mas
ctx.store.set('userSecret', user.secret);
};

// components/Header.tsx
const Header = () => {
// Acesso transparente aos dados do store
const { store } = app.useContext();
const user = store.get('user');

return (
<header>
<h1>Bem vindo, {user.name}!</h1>
{user.role === 'admin' && (
<AdminPanel />
)}
</header>
);
};









Como Funciona




  • Dados Públicos: Os dados marcados como públicos são compartilhados de forma segura com o cliente, tornando-os facilmente acessíveis para os componentes.

  • Dados Privados: Os dados sensíveis permanecem dentro do ambiente do worker e nunca são expostos ao cliente.

  • Integração com Middleware: O middleware pode popular a store com dados públicos e privados, garantindo um fluxo contínuo de informações entre a lógica do servidor e a renderização do lado do cliente.






Benefícios




  1. Segurança: A separação dos escopos de dados públicos e 2. privados garante que as informações sensíveis permaneçam protegidas.

  2. Conveniência: O acesso transparente aos dados da store simplifica o gerenciamento de estado entre worker e cliente.

  3. Flexibilidade: A store é facilmente integrada com middleware, permitindo atualizações dinâmicas de estado baseadas no tratamento de requisições.






Roteamento Elegante



O sistema de rotas do React Edge é inspirado no Hono, mas com superpoderes para SSR:




const router: App.Router = {
routes: [
routerBuilder.routeGroup({
path: '/dashboard',
// Middlewares aplicados a todas rotas do grupo
middlewares: [authMiddleware, dashboardMiddleware],
routes: [
routerBuilder.route({
path: '/',
handler: {
page: {
value: DashboardPage,
// Headers específicos para esta rota
headers: new Headers({
'Cache-Control': 'private, max-age=0'
})
}
}
}),
routerBuilder.route({
path: '/api/stats',
handler: {
// Rotas podem retornar respostas diretas
response: async (ctx) => {
const stats = await ctx.rpc.stats.getDashboardStats();
return {
value: Response.json(stats),
// Cache por 5 minutos
cache: { ttl: 300 }
};
}
}
})
]
})
]
};









Principais Recursos




  • Rotas Agrupadas: Agrupamento lógico de rotas relacionadas sob um caminho e middleware compartilhados.
    Manipuladores Flexíveis: Defina manipuladores que retornam páginas ou respostas diretas da API.

  • Cabeçalhos por Rota: Personalize cabeçalhos HTTP para rotas individuais.

  • Cache Integrado: Simplifique estratégias de cache com ttl e tags.






Benefícios




  1. Consistência: Ao agrupar rotas relacionadas, você garante a aplicação consistente de middleware e organização do código.

  2. Escalabilidade: O sistema suporta roteamento aninhado e modular para aplicações em grande escala.

  3. Desempenho: Suporte nativo para cache garante tempos de resposta ideais sem configurações manuais.






Cache Distribuído com Edge Cache



O React Edge possui um sistema de cache poderoso que funciona tanto para dados JSON quanto para páginas inteiras:




class ProductsAPI extends Rpc {
async getProducts(category: string) {
const products = await this.db.products.findByCategory(category);

return this.createResponse(products, {
cache: {
ttl: 3600, // 1 hora
tags: [`category:${category}`, 'products']
}
});
}

async updateProduct(id: string, data: ProductData) {
await this.db.products.update(id, data);

// Invalida cache específico do produto e sua categoria
await this.cache.deleteBy({
tags: [
`product:${id}`,
`category:${data.category}`
]
});
}

async searchProducts(query: string) {
const results = await this.db.products.search(query);

// Cache com prefixo para fácil invalidação
return this.createResponse(results, {
cache: {
ttl: 300,
tags: [`search:${query}`]
}
});
}
}

// Em qualquer lugar do código:
await cache.deleteBy({
// Invalida todos resultados de busca
keyPrefix: 'search:',
// E todos produtos de uma categoria
tags: ['category:electronics']
});









Principais Recursos




  • Invalidação Baseada em Tags: Entradas de cache podem ser agrupadas usando tags, permitindo invalidação fácil e seletiva quando os dados são alterados.

  • Correspondência por Prefixo: Invalide várias entradas de cache usando um prefixo comum, ideal para cenários como consultas de pesquisa ou dados hierárquicos.

  • Tempo de Vida (TTL): Defina tempos de expiração para entradas de cache para garantir dados atualizados mantendo alto desempenho.






Benefícios




  1. Desempenho Aprimorado: Reduz a carga nas APIs ao fornecer respostas em cache para dados frequentemente acessados.

  2. Escalabilidade: Gerencia eficientemente grandes conjuntos de dados e alto tráfego com um sistema de cache distribuído.

  3. Flexibilidade: Controle refinado sobre o cache, permitindo que desenvolvedores otimizem o desempenho sem sacrificar a precisão dos dados.





O componente Link é uma solução inteligente e performática para pré-carregar recursos no lado cliente, garantindo uma navegação mais fluida e rápida para os usuários. Sua funcionalidade de prefetching é ativada ao passar o cursor sobre o link, aproveitando o momento de inatividade do usuário para requisitar antecipadamente os dados do destino.



Como Funciona?




  1. Prefetch Condicional: O atributo prefetch (ativo por padrão) controla se o pré-carregamento será realizado.


  2. Cache Inteligente: Um conjunto (Set) é usado para armazenar os links já pré-carregados, evitando chamadas redundantes.


  3. Mouse Enter: Quando o usuário passa o cursor sobre o link, a função handleMouseEnter verifica se o pré-carregamento é necessário e, caso positivo, inicia uma requisição fetch para o destino.


  4. Erro Seguro: Qualquer falha na requisição é suprimida, garantindo que o comportamento do componente não seja afetado por erros momentâneos de rede.





<app.Link href=`/about` prefetch>
Sobre Nós
</app.Link>






Quando o usuário passar o mouse sobre o link “Sobre Nós”, o componente já começará a pré-carregar os dados da página /about, proporcionando uma transição quase instantânea. Idéia genial, não? Mas vi na documentação do react.dev.






app.useContext: O Portal para o Edge



O app.useContext é o hook fundamental do React Edge, proporcionando acesso a todo contexto do worker:




const DashboardPage = () => {
const {
// Parâmetros da rota atual
pathParams,
// Query params (já parseados)
searchParams,
// Rota que deu match
path,
// Rota original (com parâmetros)
rawPath,
// Proxy para RPC
rpc,
// Store compartilhado
store,
// URL completa
url
} = app.useContext<App.Context>();

// Tipagem completa do RPC
const { data } = app.useFetch(
async (ctx) => ctx.rpc.getDashboardStats()
);

// Acesso aos dados do store
const user = store.get('user');

return (
<div>
<h1>Dashboard para {user.name}</h1>
<p>Visualizando: {path}</p>
</div>
);
};









Principais Recursos do app.useContext




  • Gerenciamento de Rotas: Obtenha acesso à rota correspondente, seus parâmetros e strings de consulta sem esforço.

  • Integração RPC: Faça chamadas RPC tipadas e seguras diretamente do cliente sem configuração adicional.

  • Acesso à Store Compartilhada: Recupere ou defina valores no estado compartilhado worker-cliente com controle total sobre a visibilidade (público/privado).

  • Acesso Universal à URL: Acesse facilmente a URL completa da requisição atual para renderização e interações dinâmicas.






Por Que É Poderoso



O hook app.useContext preenche a lacuna entre o worker e o cliente. Ele permite que você construa recursos que dependem de estado compartilhado, busca segura de dados e renderização contextual sem código repetitivo. Isso simplifica aplicações complexas, tornando-as mais fáceis de manter e mais rápidas de desenvolver.






app.useUrlState: Estado Sincronizado com a URL



O hook app.useUrlState mantém o estado da sua aplicação sincronizado com os parâmetros da URL, oferecendo controle preciso sobre o que é incluído na URL, como o estado é serializado e quando é atualizado.




const ProductsPage = () => {
// Estado automaticamente sincronizado com query params
const [filters, setFilters] = app.useUrlState({
categoria: 'todos',
precoMinimo: 0,
precoMaximo: 1000,
outros: {
foo: 'bar',
baz: 'qux'
}
}, {
debounce: 500, // Atrasa atualizações da URL em 500ms
kebabCase: true, // Converte chaves para kebab-case para URLs mais limpas
omitKeys: ['filtro.locais'], // Exclui chaves específicas da URL
omitValues: [], // Exclui valores específicos da URL
pickKeys: [], // Inclui apenas chaves específicas na URL
prefix: '', // Adiciona um prefixo opcional às chaves de consulta
url: ctx.url // Usa a URL atual do contexto (funciona no servidor)
});

const { data } = app.useFetch(
async (ctx) => ctx.rpc.produtos.buscar(filters),
{
// Refetch quando filters mudar
deps: [filters]
}
);

return (
<div>
<PainelFiltros
value={filters}
onChange={(novosFiltros) => {
// URL é atualizada automaticamente
setFilters(novosFiltros);
}}
/>
<GradeProdutos data={data} />
</div>
);
};









Parâmetros





  1. Estado Inicial




    • Um objeto definindo a estrutura padrão e valores para seu estado.




  2. Opções:




    • debounce: Controla a rapidez com que a URL é atualizada após mudanças de estado.

    • kebabCase: Converte chaves de estado para kebab-case ao serializar para a URL.

    • omitKeys: Especifica chaves a serem excluídas da URL.

    • omitValues: Valores que, quando presentes, excluirão a chave associada da URL.

    • pickKeys: Limita o estado serializado para incluir apenas chaves específicas.

    • prefix: Adiciona um prefixo a todos os parâmetros de consulta.

    • url: A URL base para sincronização, geralmente derivada do contexto da aplicação.








Benefícios




  • Amigável para SEO: Garante que visualizações dependentes de estado sejam refletidas em URLs compartilháveis.

  • Atualizações com Debounce: Previne atualizações excessivas de consultas para entradas que mudam rapidamente.

  • URLs Limpas: Opções como kebabCase e omitKeys mantêm as strings de consulta legíveis.

  • Hidratação de Estado: Inicializa automaticamente o estado da URL na montagem do componente.

  • Funciona em todos ambientes: Suporta renderização no servidor e navegação no cliente.






Aplicações Práticas




  • Filtros para Listagens: Sincroniza filtros aplicados pelo usuário com a URL.

  • Visualizações Dinâmicas: Garante que zoom do mapa, pontos centrais ou outras configurações persistam.

  • Preferências do Usuário: Salva configurações selecionadas na URL para compartilhamento.






app.useStorageState: Estado Persistente



O hook app.useStorageState permite persistir estado no navegador usando localStorage ou sessionStorage com suporte completo a tipagem.




type RecentSearch = {
term: string;
date: string;
category: string;
}

type SearchState {
recentSearches: RecentSearch[];
favorites: string[];
lastSearch?: string;
}

const RecentSearches = () => {
// Inicializa o estado com tipagem e valores padrão
const [searchState, setSearchState] = app.useStorageState<SearchState>(
// Chave única para armazenamento
'user-searches',
// Estado inicial
{
recentSearches: [],
favorites: [],
lastSearch: undefined
},
// Opções de configuração
{
// Atrasa a gravação no storage por 500ms para otimizar performance
debounce: 500,

// Define o tipo de armazenamento:
// 'local' - persiste mesmo após fechar o navegador
// 'session' - persiste apenas durante a sessão
storage: 'local',

// Ignora estas chaves ao salvar no storage
omitKeys: ['lastSearch'],

// Salva apenas estas chaves específicas
pickKeys: ['recentSearches', 'favorites']
}
);

return (
<div className="recent-searches">
<h3>Buscas Recentes</h3>

{/* Lista as buscas recentes */}
<ul>
{searchState.recentSearches.map((search, index) => (
<li key={index}>
<span>{search.term}</span>
<small>{search.date}</small>

{/* Botão para favoritar busca */}
<button
onClick={() => {
setSearchState({
...searchState,
favorites: [...searchState.favorites, search.term]
})
}}
>
⭐
</button>
</li>
))}
</ul>

{/* Botão para limpar histórico */}
<button
onClick={() => {
setSearchState({
...searchState,
recentSearches: []
})
}}
>
Limpar Histórico
</button>
</div>
);
};









Opções de Persistência




  • debounce: Controla frequência de gravação

  • storage: Escolha entre localStorage e sessionStorage

  • omitKeys/pickKeys: Controle fino sobre dados persistidos






Performance




  • Atualizações otimizadas com debounce

  • Serialização/deserialização automática

  • Cache em memória






Casos de Uso Comuns




  • Histórico de pesquisas

  • Lista de favoritos

  • Preferências do usuário

  • Estado de filtros

  • Carrinho de compras temporário

  • Rascunhos de formulários






app.useDebounce: Controle de Frequência



Debounce valores reativos com facilidade:




const SearchInput = () => {
const [input, setInput] = useState('');

// Valor debounced atualiza apenas após 300ms de 'silêncio'
const debouncedValue = app.useDebounce(input, 300);

const { data } = app.useFetch(
async (ctx) => ctx.rpc.search(debouncedValue),
{
// Fetch acontece apenas quando o valor debounced muda
deps: [debouncedValue]
}
);

return (
<div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder='Buscar...'
/>
<SearchResults data={data} />
</div>
);
};









app.useDistinct: Estado sem Duplicatas



Mantenha arrays de valores únicos com tipagem:



O app.useDistinct é um hook especializado em detectar quando um valor realmente mudou, com suporte a comparação profunda e debounce:




const SearchResults = () => {
const [search, setSearch] = useState('');

// Detecta mudanças distintas no valor de busca
const {
value: currentSearch, // Valor atual
prevValue: lastSearch, // Valor anterior
distinct: hasChanged // Indica se houve mudança
} = app.useDistinct(search, {
// Debounce de 300ms
debounce: 300,
// Comparação profunda
deep: true,
// Função de comparação customizada
compare: (a, b) => a?.toLowerCase() === b?.toLowerCase()
});

// Fetch apenas quando a busca realmente mudar
const { data } = app.useFetch(
async (ctx) => ctx.rpc.search(currentSearch),
{
deps: [currentSearch],
// Só executa se houve mudança distinta
shouldFetch: () => hasChanged
}
);

return (
<div>
<input
value={search}
onChange={(e) => setSearch(e.target.value)}
/>

{hasChanged && (
<small>
Busca alterada de '{lastSearch}' para '{currentSearch}'
</small>
)}

<SearchResults data={data} />
</div>
);
};









Principais Recursos




  1. Detecção de Valor Distinto:


    • Monitora os valores atual e anterior

    • Detecta automaticamente se uma mudança é significativa com base em seus critérios



  2. Comparação Profunda:


    • Permite verificações de igualdade em nível profundo para objetos complexos



  3. Comparação Personalizada:


    • Suporta funções personalizadas para definir o que constitui uma mudança "distinta"



  4. Debounced:


    • Reduz atualizações desnecessárias quando as mudanças ocorrem com muita frequência








Benefícios




  • API idêntica ao useState: Fácil de integrar em componentes existentes.

  • Desempenho Otimizado: Evita refetching ou recálculos desnecessários quando o valor não mudou significativamente.
    UX Aprimorada: Previne atualizações excessivamente reativas da UI, resultando em interações mais suaves.

  • Lógica Simplificada: Elimina verificações manuais de igualdade ou duplicação no gerenciamento de estado.



Os hooks do React Edge foram desenhados para trabalhar em harmonia, proporcionando uma experiência de desenvolvimento fluida e tipada. A combinação deles permite criar interfaces complexas e reativas com muito menos código.






A CLI do React Edge: Potência na Ponta dos Dedos



A CLI do React Edge foi projetada para simplificar a vida dos desenvolvedores, reunindo ferramentas essenciais em uma interface única e intuitiva. Seja você iniciante ou experiente, a CLI garante que você possa configurar, desenvolver, testar e implantar projetos com eficiência e sem complicações.



Principais Recursos






Comandos Modulares e Flexíveis:




  • build: Constrói tanto o app quanto o worker, com opções para especificar ambientes e modos de desenvolvimento ou produção.

  • dev: Inicia servidores de desenvolvimento locais ou remotos, permitindo trabalhar separadamente no app ou no worker.

  • deploy: Realiza deploys rápidos e eficientes utilizando o poder combinado do Cloudflare Workers e do Cloudflare R2, garantindo performance e escalabilidade na infraestrutura edge.

  • logs: Monitora logs do worker diretamente no terminal.

  • lint: Automatiza a execução do Prettier e do ESLint, com suporte a correções automáticas.

  • test: Executa testes com cobertura opcional usando Vitest.

  • type-check: Valida a tipagem TypeScript no projeto.






Casos de Uso em Produção



Tenho o orgulho de compartilhar que a primeira aplicação em produção utilizando o React Edge já está funcionando! Trata-se de uma imobiliária brasileira, a Lopes Imóveis, que já está aproveitando toda a performance e flexibilidade do framework.



No site da imobiliária, os imóveis são carregados em cache para otimizar a busca e oferecer uma experiência mais fluida para os usuários. Por se tratar de um site extremamente dinâmico, o cache das rotas utiliza um TTL de apenas 10 segundos, combinado com a estratégia stale-while-revalidate. Isso garante que o site entregue dados atualizados com uma performance excepcional, mesmo durante revalidações em segundo plano.



Além disso, as recomendações de imóveis similares são calculadas de maneira eficiente e eventual em background, e salvas diretamente no cache da Cloudflare, utilizando o sistema de cache integrado ao RPC. Essa abordagem reduz o tempo de resposta em requisições subsequentes e torna a query das recomendações quase instantânea. Além de que todas as imagens estão armazenadas no Cloudflare R2, oferecendo armazenamento escalável e distribuído sem depender de provedores externos.



app em producao usando react edge

app em producao usando react edge



E logo teremos também o lançamento de um projeto gigantesco de marketing automatizado para a Easy Auth, mostrando ainda mais o potencial dessa tecnologia.






Conclusão



E assim, caros leitores, chegamos ao fim desta aventura pelo universo do React Edge! Sei que ainda há um mar de coisas incríveis para explorar, como as autenticações mais simples como Basic e Bearer, e outros segredinhos que fazem o dia a dia de um dev muito mais feliz. Mas calma lá! A ideia é trazer mais artigos detalhados no futuro para mergulhar de cabeça em cada uma dessas funcionalidades.



E, spoiler: logo o React Edge será open source e devidamente documentado! Conciliar desenvolvimento, trabalho, escrever e um pouquinho de vida social não é fácil, mas a empolgação de ver essa maravilha em ação, especialmente com a velocidade absurda proporcionada pela infraestrutura da Cloudflare, é o combustível que me move. Então, segura a ansiedade, porque o melhor ainda está por vir! 🚀



Enquanto isso, se você quiser começar a explorar e testar agora mesmo, o pacote já está disponível no NPM: React Edge no NPM..



Meu e-mail é [email protected], e estou sempre aberto a feedbacks, esta é só inicio desta jornada, sugestões e críticas construtivas. Se você gostou do que leu, compartilhe com seus amigos e colegas, e fique de olho nas novidades que estão por vir. Obrigado por me acompanhar até aqui, e até a próxima! 🚀🚀🚀

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - De Next.js a React Edge com Cloudflare Workers: Uma História de Libertação
id: b6236bf1-ae9d-40c3-a17c-46ebd88e3ab1
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-25
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-25"
        description = "YARA Signature for "
    strings:
        $str = "De Next.js a React Edge com Cl" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("De Nextjs a React Edge com Cloudflare Wo")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*De Nextjs a React Edge com Cloudflare Wo*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "De Nextjs a React Edge com Cloudflare Wo"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph3 Knoten / 2 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich De Next.js a React Edge com Cloudflare W.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten De Next.js a React Edge com Cloudflare Workers: Uma História de Libertação

Thematisch verwandte Begriffe: Nextjs, React, Edge, Cloudflare · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-100372 | ClipBucket v5 before 5.5.3-#197 contains a path traversal vulnerability…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag