core/landing/README.md
Tiago Yamamoto 8380a470be docs: adiciona setup completo e documentação end-to-end
- Cria .env com comentários detalhados (13 variáveis)
- Atualiza READMEs com guia completo de instalação
- Documenta setup Appwrite Cloud e schemas de collections
- Adiciona troubleshooting e guias de deploy
- Total: ~1.240 linhas de documentação em português
2025-12-11 19:55:12 -03:00

351 lines
7.3 KiB
Markdown

# Landing Page - Core Platform
> Landing page desenvolvida com **Fresh** (framework Deno) e **Tailwind CSS**. Server-side rendering para performance máxima.
## 🎯 Visão Geral
Landing page pública da plataforma DevOps, com:
- Server-Side Rendering (SSR) nativo
- Componentes interativos (Islands Architecture)
- Páginas estáticas otimizadas
- Tailwind CSS integrado
## 🛠 Stack Tecnológica
- **Framework**: [Fresh 1.7](https://fresh.deno.dev)
- **Runtime**: [Deno 2.x](https://deno.land)
- **JavaScript Library**: [Preact 10](https://preactjs.com)
- **Estilização**: Tailwind CSS 3
- **Signals**: @preact/signals
## 📦 Instalação
### Pré-requisito: Deno
```bash
# Linux/Mac
curl -fsSL https://deno.land/install.sh | sh
# Windows (PowerShell)
irm https://deno.land/install.ps1 | iex
# Verificar instalação
deno --version
```
### Dependências
Fresh gerencia dependências automaticamente via `deno.json`. Não precisa `npm install`!
As dependências são baixadas na primeira execução:
```bash
cd landing
deno task start
```
## 🏃 Scripts
Todos os scripts estão definidos em `deno.json`:
| Comando | Descrição |
|---------|-----------|
| `deno task start` | Inicia dev server (porta 8000) com hot reload |
| `deno task build` | Gera build de produção |
| `deno task preview` | Serve build de produção |
| `deno task check` | Executa fmt + lint + type-check |
| `deno task manifest` | Regenera arquivo de rotas |
### Executar em Desenvolvimento
```bash
deno task start
```
Acesse: http://localhost:8000
**Hot Reload**: Alterações em `routes/` e `islands/` recarregam automaticamente.
## 📁 Estrutura de Pastas
```
landing/
├── routes/ # 🗺️ Rotas (SSR)
│ ├── index.tsx # Homepage (/)
│ ├── _app.tsx # Layout global
│ ├── _404.tsx # Página 404
│ ├── greet/
│ │ └── [name].tsx # Rota dinâmica (/greet/:name)
│ └── api/
│ └── joke.ts # API endpoint (/api/joke)
├── islands/ # 🏝️ Componentes interativos (client-side)
│ ├── Counter.tsx # Exemplo de contador
│ └── ServerStatus.tsx # Widget de status
├── components/ # 🧩 Componentes estáticos (SSR only)
│ ├── Button.tsx
│ └── Header.tsx
├── static/ # 📦 Arquivos estáticos
│ ├── logo.svg
│ ├── favicon.ico
│ └── styles.css
├── deno.json # Configuração Deno + tarefas
├── fresh.config.ts # Configuração Fresh
├── fresh.gen.ts # Auto-gerado (manifesto de rotas)
├── main.ts # Entry point produção
├── dev.ts # Entry point desenvolvimento
└── tailwind.config.ts # Configuração Tailwind
```
## 🏗️ Arquitetura Fresh
### Routes (SSR)
Arquivos em `routes/` são renderizados no servidor:
```tsx
// routes/index.tsx
export default function Home() {
return (
<div>
<h1>Homepage</h1>
<p>Renderizado no servidor!</p>
</div>
);
}
```
Rotas dinâmicas:
```tsx
// routes/greet/[name].tsx
export default function GreetPage(props) {
const { name } = props.params;
return <h1>Olá, {name}!</h1>;
}
```
### Islands (Client-Side)
Componentes em `islands/` são hidratados no cliente:
```tsx
// islands/Counter.tsx
import { Signal, signal } from "@preact/signals";
export default function Counter() {
const count = signal(0);
return (
<div>
<p>Contador: {count}</p>
<button onClick={() => count.value++}>+1</button>
</div>
);
}
```
**Quando usar Islands**:
- Formulários interativos
- Widgets dinâmicos
- Animações client-side
**Quando usar Routes**:
- Conteúdo estático
- SEO crítico
- Performance máxima
### API Routes
```tsx
// routes/api/joke.ts
export const handler = {
GET() {
const joke = "Por que o JavaScript foi ao psicólogo? Porque tinha muitos callbacks!";
return new Response(JSON.stringify({ joke }), {
headers: { "Content-Type": "application/json" },
});
},
};
```
Acesse: http://localhost:8000/api/joke
## 🎨 Tailwind CSS
Fresh integra Tailwind via plugin:
```tsx
// Usar classes normalmente
<div class="bg-blue-500 text-white p-4 rounded-lg">
Card estilizado
</div>
```
**Configuração**: `tailwind.config.ts`
## 🧪 Testes
### Type Checking
```bash
deno task check
```
Executa:
1. `deno fmt --check` (formatação)
2. `deno lint` (linting)
3. `deno check **/*.ts` (type-check)
### Corrigir Formatação
```bash
deno fmt
```
## 🚀 Deploy
### Deno Deploy (Recomendado)
**Via GitHub (automático)**:
1. Push para GitHub
2. Conecte repo em https://dash.deno.com
3. Fresh é detectado automaticamente
4. Deploy feito em cada push
**Via CLI**:
```bash
# Instalar CLI
deno install -Arf https://deno.land/x/deploy/deployctl.ts
# Deploy
deployctl deploy --project=seu-projeto dev.ts
```
### Docker (Self-Hosted)
```dockerfile
FROM denoland/deno:alpine
WORKDIR /app
COPY . .
RUN deno cache dev.ts
EXPOSE 8000
CMD ["deno", "task", "start"]
```
```bash
docker build -t core-landing .
docker run -p 8000:8000 core-landing
```
### Fly.io
```bash
flyctl launch
flyctl deploy
```
## ⚙️ Configuração Avançada
### Variáveis de Ambiente
Fresh carrega `.env` automaticamente (se existir):
```env
# landing/.env
API_URL=https://api.example.com
```
Acesso:
```typescript
const apiUrl = Deno.env.get("API_URL");
```
**⚠️ Segurança**: Não exponha secrets no client! Use apenas em API routes.
### Custom Middleware
```tsx
// routes/_middleware.ts
export async function handler(req, ctx) {
console.log("Request:", req.url);
const resp = await ctx.next();
resp.headers.set("X-Custom-Header", "Fresh");
return resp;
}
```
### DENO_TLS_CA_STORE=system
Se sua rede usa certificados customizados:
```bash
# deno.json já inclui por padrão
DENO_TLS_CA_STORE=system deno task start
```
## 🔧 Troubleshooting
### "Import map not found"
**Solução**: Regenerar manifesto
```bash
deno task manifest
```
### Erro ao baixar dependências
**Solução**: Limpar cache
```bash
deno cache --reload dev.ts
```
### Port 8000 já em uso
**Solução**: Alterar porta em `dev.ts`
```typescript
await start(manifest, { port: 3000 });
```
### Tailwind não funciona
**Solução**: Verificar plugin em `fresh.config.ts`
```typescript
import twindPlugin from "$fresh/plugins/twind.ts";
export default {
plugins: [twindPlugin(twindConfig)],
};
```
## 📚 Recursos
- [Fresh Documentation](https://fresh.deno.dev/docs)
- [Deno Manual](https://deno.land/manual)
- [Preact Guide](https://preactjs.com/guide)
- [Islands Architecture](https://jasonformat.com/islands-architecture/)
## 🆚 Fresh vs Outros Frameworks
| Feature | Fresh | Next.js | SvelteKit |
|---------|-------|---------|-----------|
| Runtime | Deno | Node.js | Node.js |
| SSR | ✅ Nativo | ✅ | ✅ |
| Islands | ✅ Automático | ❌ | ❌ |
| Bundle size | 0 KB default | ~70 KB | ~20 KB |
| TypeScript | ✅ Nativo | Precisa config | Precisa config |
| Deploy | Deno Deploy | Vercel | Vercel/Netlify |
**Vantagens Fresh**:
- Zero JavaScript no cliente por padrão
- TypeScript sem configuração
- Deploy instantâneo (Deno Deploy)
- Deno = segurança e performance
---
Para configuração completa do monorepo, veja o [README principal](../README.md).