Compare commits
10 Commits
f00bd1055d
..
trunk
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cbc7dd529 | |||
| 2eeff8adc5 | |||
| f3c1d76ae5 | |||
| c4b8f19d6a | |||
| 555773e2e9 | |||
| f38d7885f2 | |||
| dbddcc40a2 | |||
| 22df131b57 | |||
| de85066688 | |||
| 1ebfc0e310 |
@@ -0,0 +1,10 @@
|
|||||||
|
*.local
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
README.md
|
||||||
|
.github
|
||||||
@@ -5,8 +5,8 @@ on:
|
|||||||
branches: [trunk]
|
branches: [trunk]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-push-prod:
|
build-and-push:
|
||||||
name: Build & Push (Prod)
|
name: Build & Push
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
container: git.batida.io/batida/ci-node:latest
|
container: git.batida.io/batida/ci-node:latest
|
||||||
steps:
|
steps:
|
||||||
@@ -23,24 +23,10 @@ jobs:
|
|||||||
docker push git.batida.io/batida/batida-landing:${{ github.sha }}
|
docker push git.batida.io/batida/batida-landing:${{ github.sha }}
|
||||||
docker push git.batida.io/batida/batida-landing:latest
|
docker push git.batida.io/batida/batida-landing:latest
|
||||||
|
|
||||||
deploy-staging:
|
|
||||||
name: Deploy Staging
|
|
||||||
runs-on: heavy
|
|
||||||
needs: [build-and-push-prod]
|
|
||||||
container: git.batida.io/batida/ci-node:latest
|
|
||||||
steps:
|
|
||||||
- name: Deploy to staging
|
|
||||||
run: |
|
|
||||||
echo "$KUBECONFIG_CONTENT" > /tmp/kubeconfig
|
|
||||||
kubectl --kubeconfig /tmp/kubeconfig set image deployment/batida-landing batida-landing=git.batida.io/batida/batida-landing:${{ github.sha }} -n staging
|
|
||||||
kubectl --kubeconfig /tmp/kubeconfig rollout status deployment/batida-landing -n staging --timeout=120s
|
|
||||||
env:
|
|
||||||
KUBECONFIG_CONTENT: ${{ secrets.KUBECONFIG }}
|
|
||||||
|
|
||||||
deploy-prod:
|
deploy-prod:
|
||||||
name: Deploy Prod
|
name: Deploy Prod
|
||||||
runs-on: heavy
|
runs-on: heavy
|
||||||
needs: [deploy-staging]
|
needs: [build-and-push]
|
||||||
container: git.batida.io/batida/ci-node:latest
|
container: git.batida.io/batida/ci-node:latest
|
||||||
steps:
|
steps:
|
||||||
- name: Deploy to prod
|
- name: Deploy to prod
|
||||||
|
|||||||
@@ -3,3 +3,9 @@ node_modules/
|
|||||||
output.css
|
output.css
|
||||||
package.json
|
package.json
|
||||||
package-lock.json
|
package-lock.json
|
||||||
|
|
||||||
|
# Environment
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.*.example
|
||||||
|
rust_out
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
# batida-landing
|
# batida-landing — Intent Node (Root)
|
||||||
|
|
||||||
|
## Purpose & Scope
|
||||||
Marketing/landing page for Batida. Static HTML served via Nginx.
|
Marketing/landing page for Batida. Static HTML served via Nginx.
|
||||||
Separate git repository — self-contained.
|
Separate git repository — self-contained.
|
||||||
|
|
||||||
## Structure
|
**Does:** Serve static HTML landing pages (EN + PT-BR), SEO, Nginx hosting.
|
||||||
|
**Does NOT:** Handle user data, run application logic, serve the app (→ batida-web).
|
||||||
|
|
||||||
|
## Entry Points
|
||||||
|
No build step required. Just serve static files via Nginx.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
| Depends On | Why |
|
||||||
|
|------------|-----|
|
||||||
|
| batida-infra | K8s deployment manifests, Dockerfile → Nginx container |
|
||||||
|
|
||||||
|
## Structure
|
||||||
```
|
```
|
||||||
index.html → English landing page
|
index.html → English landing page
|
||||||
index.pt-br.html → Portuguese landing page
|
index.pt-br.html → Portuguese landing page
|
||||||
@@ -17,23 +28,23 @@ sitemap.xml → SEO sitemap
|
|||||||
k8s/ → Kubernetes deployment manifests
|
k8s/ → Kubernetes deployment manifests
|
||||||
```
|
```
|
||||||
|
|
||||||
## Deployment
|
## Key Patterns
|
||||||
|
|
||||||
Deployed to Kubernetes via `batida-infra`. The Dockerfile copies static HTML into an Nginx container. Manifests in `k8s/` define the deployment.
|
|
||||||
|
|
||||||
## Key Facts
|
|
||||||
|
|
||||||
- Fully static — no build step, no JavaScript framework
|
- Fully static — no build step, no JavaScript framework
|
||||||
- Two languages: English and Portuguese (separate HTML files)
|
- Two languages: English and Portuguese (separate HTML files)
|
||||||
- Nginx handles gzip compression and static caching
|
- Nginx handles gzip compression and static caching
|
||||||
- SEO configured via robots.txt and sitemap.xml
|
- SEO configured via robots.txt and sitemap.xml
|
||||||
|
|
||||||
|
## Traps & Gotchas
|
||||||
|
- Both language versions must be updated in sync — forgetting one leaves stale content
|
||||||
|
- No hot reload or dev server — edit HTML, refresh browser
|
||||||
|
|
||||||
|
## Anti-Patterns
|
||||||
|
- Never add server-side logic or build tools — pure static HTML
|
||||||
|
- Never commit secrets or environment-specific values
|
||||||
|
- Never add JavaScript frameworks — keep it static
|
||||||
|
|
||||||
## Boundaries
|
## Boundaries
|
||||||
|
|
||||||
### Always
|
### Always
|
||||||
- Keep both language versions in sync when updating content
|
- Keep both language versions in sync when updating content
|
||||||
- Test HTML renders correctly in browser before committing
|
- Test HTML renders correctly in browser before committing
|
||||||
|
|
||||||
### Never
|
|
||||||
- Never add server-side logic or build tools — pure static HTML
|
|
||||||
- Never commit secrets or environment-specific values
|
|
||||||
|
|||||||
+26
-5
@@ -1,14 +1,25 @@
|
|||||||
FROM node:20-alpine AS build
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
||||||
COPY input.css tailwind.config.js ./
|
COPY input.css tailwind.config.js ./
|
||||||
COPY *.html ./
|
COPY *.html ./
|
||||||
RUN npx tailwindcss@3 -i input.css -o output.css --minify
|
|
||||||
|
RUN --mount=type=cache,target=/root/.npm \
|
||||||
|
npx tailwindcss@3 -i input.css -o output.css --minify
|
||||||
|
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
|
||||||
ARG APP_URL=https://app.batida.io
|
ARG APP_URL=https://app.batida.io
|
||||||
|
|
||||||
COPY --from=build /build/output.css /usr/share/nginx/html/output.css
|
RUN addgroup -g 1000 -S nginx-user && \
|
||||||
|
adduser -u 1000 -S nginx-user -G nginx-user
|
||||||
|
|
||||||
|
COPY --from=builder /build/output.css /usr/share/nginx/html/output.css
|
||||||
|
COPY favicon.png /usr/share/nginx/html/favicon.png
|
||||||
|
COPY og-image.png /usr/share/nginx/html/og-image.png
|
||||||
|
COPY robots.txt /usr/share/nginx/html/robots.txt
|
||||||
|
COPY sitemap.xml /usr/share/nginx/html/sitemap.xml
|
||||||
COPY index.html /tmp/index.html
|
COPY index.html /tmp/index.html
|
||||||
COPY index.pt-br.html /tmp/index.pt-br.html
|
COPY index.pt-br.html /tmp/index.pt-br.html
|
||||||
COPY vs.html /tmp/vs.html
|
COPY vs.html /tmp/vs.html
|
||||||
@@ -22,8 +33,18 @@ RUN sed -i "s|{{APP_URL}}|${APP_URL}|g" /tmp/index.html && \
|
|||||||
mv /tmp/index.html /usr/share/nginx/html/index.html && \
|
mv /tmp/index.html /usr/share/nginx/html/index.html && \
|
||||||
mv /tmp/index.pt-br.html /usr/share/nginx/html/pt-br/index.html && \
|
mv /tmp/index.pt-br.html /usr/share/nginx/html/pt-br/index.html && \
|
||||||
mv /tmp/vs.html /usr/share/nginx/html/vs.html && \
|
mv /tmp/vs.html /usr/share/nginx/html/vs.html && \
|
||||||
mv /tmp/vs.pt-br.html /usr/share/nginx/html/pt-br/vs.html
|
mv /tmp/vs.pt-br.html /usr/share/nginx/html/pt-br/vs.html && \
|
||||||
|
chown -R nginx-user:nginx-user /usr/share/nginx/html && \
|
||||||
|
chown -R nginx-user:nginx-user /var/cache/nginx && \
|
||||||
|
chown -R nginx-user:nginx-user /var/log/nginx && \
|
||||||
|
chown -R nginx-user:nginx-user /etc/nginx/conf.d && \
|
||||||
|
touch /run/nginx.pid && \
|
||||||
|
chown -R nginx-user:nginx-user /run/nginx.pid
|
||||||
|
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
EXPOSE 80
|
USER nginx-user
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
"""Generate OG image and favicon for Batida landing page."""
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
|
# OG Image (1200x630)
|
||||||
|
W, H = 1200, 630
|
||||||
|
img = Image.new("RGB", (W, H), "#0C0C0F")
|
||||||
|
draw = ImageDraw.Draw(img)
|
||||||
|
|
||||||
|
# Orange accent bar at top
|
||||||
|
draw.rectangle([0, 0, W, 6], fill="#F97316")
|
||||||
|
|
||||||
|
# Logo square (orange B)
|
||||||
|
logo_size = 120
|
||||||
|
logo_x, logo_y = 80, 180
|
||||||
|
draw.rounded_rectangle([logo_x, logo_y, logo_x + logo_size, logo_y + logo_size], radius=24, fill="#F97316")
|
||||||
|
try:
|
||||||
|
font_bold = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 72)
|
||||||
|
font_title = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 64)
|
||||||
|
font_sub = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 28)
|
||||||
|
font_tag = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 22)
|
||||||
|
except Exception:
|
||||||
|
font_bold = ImageFont.load_default()
|
||||||
|
font_title = ImageFont.load_default()
|
||||||
|
font_sub = ImageFont.load_default()
|
||||||
|
font_tag = ImageFont.load_default()
|
||||||
|
|
||||||
|
# B letter in logo
|
||||||
|
bbox = draw.textbbox((0, 0), "B", font=font_bold)
|
||||||
|
bw, bh = bbox[2] - bbox[0], bbox[3] - bbox[1]
|
||||||
|
draw.text((logo_x + (logo_size - bw) / 2, logo_y + (logo_size - bh) / 2 - 8), "B", fill="white", font=font_bold)
|
||||||
|
|
||||||
|
# Title
|
||||||
|
draw.text((240, 185), "Batida", fill="#FAFAFA", font=font_title)
|
||||||
|
|
||||||
|
# Tagline
|
||||||
|
draw.text((240, 270), "Manage Incidents. Keep Your Cool.", fill="#6B6B80", font=font_sub)
|
||||||
|
|
||||||
|
# Bottom tagline
|
||||||
|
draw.text((80, 460), "Intelligent incident management for DevOps teams.", fill="#4A4A5A", font=font_tag)
|
||||||
|
draw.text((80, 495), "pagerduty alternative • open core • self-hosted or cloud", fill="#3A3A4A", font=font_tag)
|
||||||
|
|
||||||
|
# CTA button
|
||||||
|
btn_x, btn_y, btn_w, btn_h = 80, 550, 200, 44
|
||||||
|
draw.rounded_rectangle([btn_x, btn_y, btn_x + btn_w, btn_y + btn_h], radius=8, fill="#F97316")
|
||||||
|
bbox = draw.textbbox((0, 0), "Get Started", font=font_tag)
|
||||||
|
tw = bbox[2] - bbox[0]
|
||||||
|
draw.text((btn_x + (btn_w - tw) / 2, btn_y + 10), "Get Started", fill="white", font=font_tag)
|
||||||
|
|
||||||
|
# URL
|
||||||
|
draw.text((960, 580), "batida.io", fill="#3A3A4A", font=font_tag)
|
||||||
|
|
||||||
|
img.save("/Users/kakarotto/codes/personal/batida/batida-landing/og-image.png", "PNG")
|
||||||
|
print("OG image created: og-image.png")
|
||||||
|
|
||||||
|
# Favicon PNG (32x32)
|
||||||
|
fav = Image.new("RGBA", (32, 32), (0, 0, 0, 0))
|
||||||
|
fav_draw = ImageDraw.Draw(fav)
|
||||||
|
fav_draw.rounded_rectangle([0, 0, 32, 32], radius=8, fill="#F97316")
|
||||||
|
try:
|
||||||
|
fav_font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 20)
|
||||||
|
except Exception:
|
||||||
|
fav_font = ImageFont.load_default()
|
||||||
|
bbox = fav_draw.textbbox((0, 0), "B", font=fav_font)
|
||||||
|
bw, bh = bbox[2] - bbox[0], bbox[3] - bbox[1]
|
||||||
|
fav_draw.text(((32 - bw) / 2, (32 - bh) / 2 - 2), "B", fill="white", font=fav_font)
|
||||||
|
fav.save("/Users/kakarotto/codes/personal/batida/batida-landing/favicon.png", "PNG")
|
||||||
|
print("Favicon created: favicon.png")
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 468 B |
@@ -8,6 +8,7 @@
|
|||||||
<title>Batida — Manage Incidents. Keep Your Cool.</title>
|
<title>Batida — Manage Incidents. Keep Your Cool.</title>
|
||||||
<meta name="description" content="Intelligent alternative to PagerDuty. Incident management platform for DevOps teams that need to respond fast, coordinate without chaos, and learn from every problem.">
|
<meta name="description" content="Intelligent alternative to PagerDuty. Incident management platform for DevOps teams that need to respond fast, coordinate without chaos, and learn from every problem.">
|
||||||
<link rel="canonical" href="https://batida.io/">
|
<link rel="canonical" href="https://batida.io/">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png">
|
||||||
|
|
||||||
<!-- Open Graph -->
|
<!-- Open Graph -->
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
@@ -15,11 +16,15 @@
|
|||||||
<meta property="og:title" content="Batida — Manage Incidents. Keep Your Cool.">
|
<meta property="og:title" content="Batida — Manage Incidents. Keep Your Cool.">
|
||||||
<meta property="og:description" content="Intelligent alternative to PagerDuty. Incident management platform for DevOps teams. Start free.">
|
<meta property="og:description" content="Intelligent alternative to PagerDuty. Incident management platform for DevOps teams. Start free.">
|
||||||
<meta property="og:site_name" content="Batida">
|
<meta property="og:site_name" content="Batida">
|
||||||
|
<meta property="og:image" content="https://batida.io/og-image.png">
|
||||||
|
<meta property="og:image:width" content="1200">
|
||||||
|
<meta property="og:image:height" content="630">
|
||||||
|
|
||||||
<!-- Twitter Card -->
|
<!-- Twitter Card -->
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:title" content="Batida — Manage Incidents. Keep Your Cool.">
|
<meta name="twitter:title" content="Batida — Manage Incidents. Keep Your Cool.">
|
||||||
<meta name="twitter:description" content="Intelligent alternative to PagerDuty. Incident management platform for DevOps teams.">
|
<meta name="twitter:description" content="Intelligent alternative to PagerDuty. Incident management platform for DevOps teams.">
|
||||||
|
<meta name="twitter:image" content="https://batida.io/og-image.png">
|
||||||
|
|
||||||
<!-- Sitemap -->
|
<!-- Sitemap -->
|
||||||
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
|
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
|
||||||
@@ -489,6 +494,9 @@
|
|||||||
font-size: clamp(1.5rem, 4vw, 3rem);
|
font-size: clamp(1.5rem, 4vw, 3rem);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- Analytics: Plausible (privacy-friendly, GDPR compliant) -->
|
||||||
|
<script defer data-domain="batida.io" src="https://plausible.io/js/script.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="antialiased">
|
<body class="antialiased">
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
<title>Batida — Gerencie Incidentes. Mantenha a Calma.</title>
|
<title>Batida — Gerencie Incidentes. Mantenha a Calma.</title>
|
||||||
<meta name="description" content="Plataforma moderna de incident management. Alternativa inteligente ao PagerDuty. Setup em minutos. Comece grátis.">
|
<meta name="description" content="Plataforma moderna de incident management. Alternativa inteligente ao PagerDuty. Setup em minutos. Comece grátis.">
|
||||||
<link rel="canonical" href="https://batida.io/pt-br">
|
<link rel="canonical" href="https://batida.io/pt-br">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png">
|
||||||
|
|
||||||
<!-- Open Graph -->
|
<!-- Open Graph -->
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
@@ -15,11 +16,15 @@
|
|||||||
<meta property="og:title" content="Batida — Gerencie Incidentes. Mantenha a Calma.">
|
<meta property="og:title" content="Batida — Gerencie Incidentes. Mantenha a Calma.">
|
||||||
<meta property="og:description" content="Plataforma moderna de incident management. Alternativa inteligente ao PagerDuty. Setup em minutos. Comece grátis.">
|
<meta property="og:description" content="Plataforma moderna de incident management. Alternativa inteligente ao PagerDuty. Setup em minutos. Comece grátis.">
|
||||||
<meta property="og:site_name" content="Batida">
|
<meta property="og:site_name" content="Batida">
|
||||||
|
<meta property="og:image" content="https://batida.io/og-image.png">
|
||||||
|
<meta property="og:image:width" content="1200">
|
||||||
|
<meta property="og:image:height" content="630">
|
||||||
|
|
||||||
<!-- Twitter Card -->
|
<!-- Twitter Card -->
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:title" content="Batida — Gerencie Incidentes. Mantenha a Calma.">
|
<meta name="twitter:title" content="Batida — Gerencie Incidentes. Mantenha a Calma.">
|
||||||
<meta name="twitter:description" content="Plataforma moderna de incident management. Alternativa inteligente ao PagerDuty.">
|
<meta name="twitter:description" content="Plataforma moderna de incident management. Alternativa inteligente ao PagerDuty.">
|
||||||
|
<meta name="twitter:image" content="https://batida.io/og-image.png">
|
||||||
|
|
||||||
<!-- Sitemap -->
|
<!-- Sitemap -->
|
||||||
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
|
<link rel="sitemap" type="application/xml" href="/sitemap.xml">
|
||||||
@@ -489,6 +494,9 @@
|
|||||||
font-size: clamp(1.5rem, 4vw, 3rem);
|
font-size: clamp(1.5rem, 4vw, 3rem);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<!-- Analytics: Plausible (privacy-friendly, GDPR compliant) -->
|
||||||
|
<script defer data-domain="batida.io" src="https://plausible.io/js/script.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="antialiased">
|
<body class="antialiased">
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -24,11 +24,11 @@ spec:
|
|||||||
- name: batida-landing
|
- name: batida-landing
|
||||||
image: git.batida.io/batida/batida-landing:latest
|
image: git.batida.io/batida/batida-landing:latest
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 80
|
- containerPort: 8080
|
||||||
livenessProbe:
|
livenessProbe:
|
||||||
httpGet:
|
httpGet:
|
||||||
path: /
|
path: /
|
||||||
port: 80
|
port: 8080
|
||||||
initialDelaySeconds: 5
|
initialDelaySeconds: 5
|
||||||
periodSeconds: 30
|
periodSeconds: 30
|
||||||
resources:
|
resources:
|
||||||
@@ -49,4 +49,4 @@ spec:
|
|||||||
app: batida-landing
|
app: batida-landing
|
||||||
ports:
|
ports:
|
||||||
- port: 80
|
- port: 80
|
||||||
targetPort: 80
|
targetPort: 8080
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 8080;
|
||||||
server_name _;
|
server_name _;
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||||
|
<rect width="32" height="32" rx="8" fill="#F97316"/>
|
||||||
|
<text x="16" y="23" font-family="Arial,sans-serif" font-size="20" font-weight="bold" fill="white" text-anchor="middle">B</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 253 B |
@@ -8,16 +8,21 @@
|
|||||||
<title>Batida vs PagerDuty vs Grafana OnCall — Feature Comparison</title>
|
<title>Batida vs PagerDuty vs Grafana OnCall — Feature Comparison</title>
|
||||||
<meta name="description" content="Compare Batida with PagerDuty and Grafana OnCall. See pricing, features, LGPD compliance, and why Brazilian teams choose Batida.">
|
<meta name="description" content="Compare Batida with PagerDuty and Grafana OnCall. See pricing, features, LGPD compliance, and why Brazilian teams choose Batida.">
|
||||||
<link rel="canonical" href="https://batida.io/vs">
|
<link rel="canonical" href="https://batida.io/vs">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png">
|
||||||
|
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:url" content="https://batida.io/vs">
|
<meta property="og:url" content="https://batida.io/vs">
|
||||||
<meta property="og:title" content="Batida vs PagerDuty vs Grafana OnCall — Feature Comparison">
|
<meta property="og:title" content="Batida vs PagerDuty vs Grafana OnCall — Feature Comparison">
|
||||||
<meta property="og:description" content="Compare incident management platforms. See why Batida is the best choice for Brazilian DevOps teams.">
|
<meta property="og:description" content="Compare incident management platforms. See why Batida is the best choice for Brazilian DevOps teams.">
|
||||||
<meta property="og:site_name" content="Batida">
|
<meta property="og:site_name" content="Batida">
|
||||||
|
<meta property="og:image" content="https://batida.io/og-image.png">
|
||||||
|
<meta property="og:image:width" content="1200">
|
||||||
|
<meta property="og:image:height" content="630">
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:title" content="Batida vs PagerDuty vs Grafana OnCall">
|
<meta name="twitter:title" content="Batida vs PagerDuty vs Grafana OnCall">
|
||||||
<meta name="twitter:description" content="Compare incident management platforms for Brazilian teams.">
|
<meta name="twitter:description" content="Compare incident management platforms for Brazilian teams.">
|
||||||
|
<meta name="twitter:image" content="https://batida.io/og-image.png">
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
@@ -70,6 +75,9 @@
|
|||||||
.compare-table .partial { color: #F59E0B; }
|
.compare-table .partial { color: #F59E0B; }
|
||||||
.compare-table .batida-col { color: #F97316; font-weight: 600; }
|
.compare-table .batida-col { color: #F97316; font-weight: 600; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- Analytics: Plausible (privacy-friendly, GDPR compliant) -->
|
||||||
|
<script defer data-domain="batida.io" src="https://plausible.io/js/script.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="antialiased">
|
<body class="antialiased">
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,21 @@
|
|||||||
<title>Batida vs PagerDuty vs Grafana OnCall — Comparação de Recursos</title>
|
<title>Batida vs PagerDuty vs Grafana OnCall — Comparação de Recursos</title>
|
||||||
<meta name="description" content="Compare o Batida com PagerDuty e Grafana OnCall. Veja preços, recursos, conformidade LGPD e por que equipes brasileiras escolhem o Batida.">
|
<meta name="description" content="Compare o Batida com PagerDuty e Grafana OnCall. Veja preços, recursos, conformidade LGPD e por que equipes brasileiras escolhem o Batida.">
|
||||||
<link rel="canonical" href="https://batida.io/vs/pt-br">
|
<link rel="canonical" href="https://batida.io/vs/pt-br">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon.png">
|
||||||
|
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:url" content="https://batida.io/vs/pt-br">
|
<meta property="og:url" content="https://batida.io/vs/pt-br">
|
||||||
<meta property="og:title" content="Batida vs PagerDuty vs Grafana OnCall — Comparação">
|
<meta property="og:title" content="Batida vs PagerDuty vs Grafana OnCall — Comparação">
|
||||||
<meta property="og:description" content="Compare plataformas de gerenciamento de incidentes. Veja por que o Batida é a melhor escolha para equipes DevOps brasileiras.">
|
<meta property="og:description" content="Compare plataformas de gerenciamento de incidentes. Veja por que o Batida é a melhor escolha para equipes DevOps brasileiras.">
|
||||||
<meta property="og:site_name" content="Batida">
|
<meta property="og:site_name" content="Batida">
|
||||||
|
<meta property="og:image" content="https://batida.io/og-image.png">
|
||||||
|
<meta property="og:image:width" content="1200">
|
||||||
|
<meta property="og:image:height" content="630">
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
<meta name="twitter:title" content="Batida vs PagerDuty vs Grafana OnCall">
|
<meta name="twitter:title" content="Batida vs PagerDuty vs Grafana OnCall">
|
||||||
<meta name="twitter:description" content="Compare plataformas de gerenciamento de incidentes para equipes brasileiras.">
|
<meta name="twitter:description" content="Compare plataformas de gerenciamento de incidentes para equipes brasileiras.">
|
||||||
|
<meta name="twitter:image" content="https://batida.io/og-image.png">
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
@@ -70,6 +75,9 @@
|
|||||||
.compare-table .partial { color: #F59E0B; }
|
.compare-table .partial { color: #F59E0B; }
|
||||||
.compare-table .batida-col { color: #F97316; font-weight: 600; }
|
.compare-table .batida-col { color: #F97316; font-weight: 600; }
|
||||||
</style>
|
</style>
|
||||||
|
<!-- Analytics: Plausible (privacy-friendly, GDPR compliant) -->
|
||||||
|
<script defer data-domain="batida.io" src="https://plausible.io/js/script.js"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class="antialiased">
|
<body class="antialiased">
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user