Veja primeiro a consola
Abra a página, e depois a consola do browser. No Chrome num Mac, é o menu View, depois Developer, depois JavaScript Console, com estes nomes no Chrome em inglês, ou Cmd+Option+J em qualquer idioma; no Windows, Ctrl+Shift+J. A primeira linha a vermelho diz qual destes é:
Uncaught SyntaxError: Unexpected token '<': o browser não consegue ler JSX.Failed to resolve module specifier "react", ouCannot use import statement outside a module: os imports não apontam para lado 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 a partir do seu disco.
1. O browser não consegue ler JSX
Uma linha como return <div className="p-8">…</div> é JSX, não JavaScript. Alguma coisa tem de a converter em chamadas de funções antes de um browser a correr. Numa etiqueta <script> normal, o browser não consegue ler o script a partir do primeiro < que não espera, por isso nada do script corre. Guardado como ficheiro .jsx e aberto diretamente, nem sequer corre: o browser mostra o código como texto, ou transfere-o.
A solução é um passo de conversão: um bundler como o Vite ou o esbuild, antes de a página ir para qualquer lado. Para um teste rápido, o Babel consegue converter o JSX no browser com <script type="text/babel">, o que ainda deixa por resolver os imports da secção seguinte.
2. Os imports não apontam para lado nenhum
Os ficheiros 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 browser não faz ideia do que é react. Num script de módulo, um nome solto como este é um erro até alguma coisa o associar 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 nomeia é um componente do shadcn/ui, um ficheiro que não existe fora do Claude até o adicionar.
A solução é um bundler que instala os pacotes a partir do npm, ou um import map que diz ao browser onde está cada um:
<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>Cada pacote que usa React tem de partilhar a única cópia que a página tem dele, 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 ficheiro do Claude termina com export default function App() { … }. Isso define um componente, mas não o põe na página. No Claude, é a janela que faz esse passo. Sozinho, o ficheiro define uma função que nada chama, o que não é um erro, por isso a consola fica calada e a página fica vazia.
Uma página precisa de um elemento onde desenhar o componente, e de uma chamada que o desenhe:
<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 ficheiro já convertido, não o JSX, e tem de vir de um endereço web (secção 5). Tutoriais mais antigos usam ReactDOM.render em vez disso: o React 18 tornou-o obsoleto e o React 19 removeu-o, por isso num React atual falha com um TypeError.
4. As classes do Tailwind não fazem nada
O Claude dá estilo aos ficheiros 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 simples não os inclui, por isso as classes são só nomes.
Este raramente fica completamente em branco: o conteúdo está lá, sem estilo, empilhado junto à margem esquerda. Parece em branco quando o texto devia estar sobre um fundo escuro e agora é branco sobre branco, ou quando o layout depende de classes como h-screen e flex para dar tamanho a alguma coisa.
A solução é o próprio Tailwind. Num build, procura nomes de classes nos seus ficheiros e escreve o CSS que usam. Para um teste rápido há o Play CDN do Tailwind, um script que faz o mesmo no browser, e que a documentação do Tailwind descreve como feito para desenvolvimento, não para produção.
5. A página foi aberta a partir do seu disco
Faça duplo clique num ficheiro HTML e ele abre num endereço file:///. Uma página aí 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 ficheiro,
<script type="module" src="app.js">. Os scripts de módulo são obtidos segundo 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 vai buscar esse ficheiro por si e é recusado da mesma forma. - Um
fetch()de um ficheiro JSON ou CSV que está ao lado da página.
O código escrito dentro da página continua a correr, e os imports de endereços https que o permitem, como o esm.sh, continuam a carregar. A solução é servir a pasta a partir 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. Corra qualquer um deles na pasta:
npx serve
python3 -m http.serverOu salte os cinco
Cole o ficheiro no Solta, na caixa lá em cima. Quando o publica, o Solta converte o JSX, aponta cada import para o esm.sh, com uma versão fixa para os pacotes que estes ficheiros costumam importar, serve os componentes shadcn/ui a partir da sua própria cópia, gera o CSS das classes do Tailwind que o ficheiro usa, e monta o export default numa página. A página é servida num endereço https, por isso as regras do file:/// nunca entram em jogo.
Se o ficheiro 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 não consegue resolver é 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
Porque é que o meu ficheiro React do Claude mostra uma página em branco?
Porque no Claude a janela à volta dele converte o JSX, fornece os pacotes que os imports nomeiam, monta o componente e carrega o Tailwind. Aberto diretamente num browser, ou num alojamento que serve os ficheiros tal como são, nada disso acontece.
O que quer dizer Unexpected token '<' na consola?
Que o browser encontrou JSX, que não é JavaScript. Tem de ser convertido antes, com um bundler como o Vite ou o esbuild, ou, para um teste rápido, com o Babel no browser.
Como resolver Failed to resolve module specifier "react"?
Com um bundler que instala os pacotes a partir do npm, ou com um import map que diz ao browser onde está cada pacote, por exemplo no esm.sh. Cada pacote que usa React tem de partilhar a mesma cópia dele, senão a página falha com Invalid hook call.
Porque é que a página fica vazia e a consola não mostra nenhum erro?
Porque nada monta o componente: o ficheiro 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 desenhe nele o componente.
Porque é que a página não funciona quando abro o ficheiro com duplo clique?
Abre num endereço file:///, e o Chrome e o Edge recusam um script de módulo de outro ficheiro e um fetch() de um ficheiro ao lado. Sirva a pasta a partir de um servidor local, com npx serve ou python3 -m http.server, e abra-a em http://localhost.

