Leia o console primeiro
Abra a página, e depois o console do navegador. No Chrome num Mac, é o menu View, depois Developer, depois JavaScript Console, com esses nomes no Chrome em inglês, ou Cmd+Option+J em qualquer idioma; no Windows, Ctrl+Shift+J. A primeira linha vermelha diz qual destes é:
Uncaught SyntaxError: Unexpected token '<': o navegador não consegue ler JSX.Failed to resolve module specifier "react", ouCannot use import statement outside a module: os imports não apontam para lugar nenhum.- Nada, e a página está vazia: nada monta o componente.
- Está tudo lá, mas sem estilo: as classes do Tailwind não fazem nada.
has been blocked by CORS policy, num endereçofile:///: a página foi aberta do seu disco.
1. O navegador não consegue ler JSX
Uma linha como return <div className="p-8">…</div> é JSX, não JavaScript. Alguma coisa precisa convertê-la em chamadas de função antes de um navegador rodá-la. Numa tag <script> comum, o navegador não consegue ler o script depois do primeiro < que não espera, então nada do script roda. Salvo como arquivo .jsx e aberto direto, ele nem chega a rodar: o navegador mostra o código como texto, ou baixa o arquivo.
A correção é uma etapa de conversão: um bundler como o Vite ou o esbuild, antes de a página ir para qualquer lugar. Para um teste rápido, o Babel consegue converter o JSX no navegador com <script type="text/babel">, o que ainda deixa os imports da próxima seção por resolver.
2. Os imports não apontam para lugar nenhum
Os arquivos React do Claude começam com linhas como estas:
import { useState } from "react";
import { LineChart, Line } from "recharts";
import { Card } from "@/components/ui/card";No Claude, a janela fornece esses pacotes. Um navegador não faz ideia do que é react. Num script de módulo, um nome solto como esse é um erro até que alguma coisa o ligue a um endereço; num script clássico, o próprio import é um erro de sintaxe. O @/ da terceira linha é um atalho de caminho da configuração de um projeto, e o Card que ele nomeia é um componente do shadcn/ui, um arquivo que não existe fora do Claude até você adicioná-lo.
A correção é um bundler que instala os pacotes do npm, ou um import map que diz ao navegador onde cada um está:
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@18.3.1",
"react/jsx-runtime": "https://esm.sh/react@18.3.1/jsx-runtime",
"react-dom/client": "https://esm.sh/react-dom@18.3.1/client?external=react"
}
}
</script>Todo pacote que usa React precisa compartilhar a única cópia dele que a página tem, e é isso que ?external=react pede ao esm.sh. Com duas cópias, a página falha com Invalid hook call.
3. Nada monta o componente
O arquivo do Claude termina com export default function App() { … }. Isso define um componente, mas não o coloca na página. No Claude, é a janela que faz essa etapa. Sozinho, o arquivo define uma função que nada chama, o que não é um erro, então o console fica quieto e a página fica vazia.
Uma página precisa de um elemento onde desenhar o componente, e de uma chamada que o desenha:
<div id="root"></div>
<script type="module">
import { createElement } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.js";
createRoot(document.getElementById("root"))
.render(createElement(App));
</script>Aqui App.js é o arquivo já convertido, não o JSX, e ele precisa vir de um endereço da web (seção 5). Tutoriais mais antigos usam ReactDOM.render no lugar: o React 18 o declarou obsoleto e o React 19 o removeu, então num React atual ele falha com um TypeError.
4. As classes do Tailwind não fazem nada
O Claude estiliza os arquivos React com classes do Tailwind, como className="p-8 rounded-xl bg-slate-900 text-white". No Claude, a janela inclui os estilos do Tailwind. Uma página comum não inclui, então as classes são só nomes.
Este quase nunca fica totalmente em branco: o conteúdo está lá, sem estilo, empilhado na borda esquerda. Parece em branco quando o texto devia ficar sobre um fundo escuro e agora é branco no branco, ou quando o layout depende de classes como h-screen e flex para dar tamanho a alguma coisa.
A correção é o próprio Tailwind. Num build, ele procura nomes de classe nos seus arquivos e escreve o CSS que eles usam. Para um teste rápido existe o Play CDN do Tailwind, um script que faz o mesmo no navegador, e que a documentação do Tailwind descreve como feito para desenvolvimento, não para produção.
5. A página foi aberta do seu disco
Dê dois cliques num arquivo HTML e ele abre num endereço file:///. Uma página ali não tem uma origem web própria, e o Chrome e o Edge recusam parte do que ela pede:
- Um script de módulo de outro arquivo,
<script type="module" src="app.js">. Scripts de módulo são buscados sob as regras de CORS, que uma páginafile:///não consegue cumprir. - O
<script type="text/babel" src="App.jsx">do Babel, porque o Babel busca esse arquivo por conta própria e é recusado do mesmo jeito. - Um
fetch()de um arquivo JSON ou CSV que está ao lado da página.
O código escrito dentro da página continua rodando, e imports de endereços https que permitem isso, como o esm.sh, continuam carregando. A correção é servir a pasta de um servidor web local e abri-la em http://localhost, na porta que o servidor usa: 3000 para o primeiro destes, 8000 para o segundo. Rode qualquer um deles na pasta:
npx serve
python3 -m http.serverOu pule os cinco
Cole o arquivo no Solta, na caixa lá em cima. Quando você publica, o Solta converte o JSX, aponta cada import para o esm.sh, com uma versão fixa para os pacotes que esses arquivos costumam importar, serve os componentes shadcn/ui da própria cópia dele, gera o CSS das classes do Tailwind que o arquivo usa, e monta o export default numa página. A página é servida num endereço https, então as regras do file:/// nunca entram em jogo.
Se o arquivo não tem export default e não se monta sozinho, o Solta não o publica, e diz o que acrescentar. Se o componente dá erro enquanto é desenhado, a página mostra o erro em vez de uma página branca. O que ele não consegue corrigir é um pacote que o esm.sh não tem, ou qualquer coisa que precise de um servidor: o que não funciona. Uma página que pergunta algo ao Claude enquanto as pessoas a usam também precisa que essa chamada mude: como um site chama um modelo.
Perguntas
Por que meu arquivo React do Claude mostra uma página em branco?
Porque no Claude a janela em volta dele converte o JSX, fornece os pacotes que os imports nomeiam, monta o componente e carrega o Tailwind. Aberto direto num navegador, ou numa hospedagem que serve arquivos do jeito que são, nada disso acontece.
O que quer dizer Unexpected token '<' no console?
Que o navegador encontrou JSX, que não é JavaScript. Ele precisa ser convertido antes, com um bundler como o Vite ou o esbuild, ou, para um teste rápido, com o Babel no navegador.
Como corrigir Failed to resolve module specifier "react"?
Com um bundler que instala os pacotes do npm, ou com um import map que diz ao navegador onde cada pacote está, por exemplo no esm.sh. Todo pacote que usa React precisa compartilhar a mesma cópia dele, ou a página falha com Invalid hook call.
Por que a página fica vazia e o console não mostra erro nenhum?
Porque nada monta o componente: o arquivo define uma função que nada chama, o que não é um erro. A página precisa de um elemento onde desenhar e de uma chamada a createRoot que desenha o componente nele.
Por que a página não funciona quando abro o arquivo com dois cliques?
Ela abre num endereço file:///, e o Chrome e o Edge recusam um script de módulo de outro arquivo e um fetch() de um arquivo ao lado. Sirva a pasta de um servidor local, com npx serve ou python3 -m http.server, e abra em http://localhost.

