diff --git a/next.config.ts b/next.config.ts
index 395e952..7c57f80 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -53,9 +53,19 @@ const nextConfig: NextConfig = {
key: "Content-Security-Policy",
value: cspHeader.replace(/\s{2,}/g, " ").trim(),
},
+ {
+ key: "Strict-Transport-Security",
+ value: "max-age=63072000; includeSubDomains; preload",
+ },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "X-Frame-Options", value: "DENY" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
+ { key: "X-DNS-Prefetch-Control", value: "on" },
+ {
+ key: "Permissions-Policy",
+ value:
+ "camera=(), microphone=(), geolocation=(self), interest-cohort=()",
+ },
],
},
{
diff --git a/public/aeris-hero.png b/public/aeris-hero.png
new file mode 100644
index 0000000..e186de9
Binary files /dev/null and b/public/aeris-hero.png differ
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 8e854ce..a30e9f4 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -14,25 +14,43 @@ const GA_ID = process.env.NEXT_PUBLIC_GA_ID;
const title = "Aeris — Real-Time 3D Flight Tracking";
const description =
- "Track live flights in 3D over the world's busiest airspaces. Altitude-aware, beautifully rendered, and completely free.";
+ "Track live flights in stunning 3D over the world's busiest airspaces. See real-time ADS-B data with altitude-aware rendering — low altitudes glow cyan, high altitudes shift to gold. Free and open source.";
const siteUrl = "https://aeris.edbn.me";
export const metadata: Metadata = {
- title,
- description,
metadataBase: new URL(siteUrl),
+ title: {
+ default: title,
+ template: "%s | Aeris",
+ },
+ description,
+ applicationName: "Aeris",
keywords: [
"flight tracker",
- "live flights",
+ "live flight tracker",
"3D flight tracking",
- "real-time aviation",
+ "real-time flight tracker",
"flight radar",
- "aircraft tracking",
- "aeris",
- "opensky",
+ "aircraft tracker",
+ "plane tracker",
+ "ADS-B tracker",
+ "live aircraft map",
+ "flight tracking map",
+ "airplane tracker live",
+ "aviation tracker",
+ "track flights live",
+ "free flight tracker",
+ "aeris flight tracker",
+ "opensky network",
+ "airplanes live",
+ "adsb tracker",
+ "live air traffic",
+ "flight path tracker",
],
authors: [{ name: "kewonit", url: "https://github.com/kewonit" }],
creator: "kewonit",
+ publisher: "kewonit",
+ category: "travel",
openGraph: {
type: "website",
locale: "en_US",
@@ -49,9 +67,25 @@ export const metadata: Metadata = {
robots: {
index: true,
follow: true,
- googleBot: { index: true, follow: true },
+ nocache: false,
+ googleBot: {
+ index: true,
+ follow: true,
+ "max-video-preview": -1,
+ "max-image-preview": "large",
+ "max-snippet": -1,
+ },
},
alternates: { canonical: siteUrl },
+ icons: {
+ icon: "/favicon.ico",
+ },
+ other: {
+ "mobile-web-app-capable": "yes",
+ "apple-mobile-web-app-capable": "yes",
+ "apple-mobile-web-app-status-bar-style": "black-translucent",
+ "apple-mobile-web-app-title": "Aeris",
+ },
};
export default function RootLayout({
diff --git a/src/app/manifest.ts b/src/app/manifest.ts
new file mode 100644
index 0000000..d401692
--- /dev/null
+++ b/src/app/manifest.ts
@@ -0,0 +1,22 @@
+import type { MetadataRoute } from "next";
+
+export default function manifest(): MetadataRoute.Manifest {
+ return {
+ name: "Aeris — Real-Time 3D Flight Tracking",
+ short_name: "Aeris",
+ description:
+ "Track live flights in 3D over the world's busiest airspaces. Altitude-aware, beautifully rendered, and completely free.",
+ start_url: "/",
+ display: "standalone",
+ background_color: "#000000",
+ theme_color: "#000000",
+ icons: [
+ {
+ src: "/favicon.ico",
+ sizes: "any",
+ type: "image/x-icon",
+ },
+ ],
+ categories: ["travel", "navigation", "utilities"],
+ };
+}
diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx
new file mode 100644
index 0000000..2129a34
--- /dev/null
+++ b/src/app/not-found.tsx
@@ -0,0 +1,73 @@
+import type { Metadata } from "next";
+import Link from "next/link";
+
+export const metadata: Metadata = {
+ title: "Page Not Found",
+ description:
+ "The page you are looking for does not exist. Return to Aeris to track live flights in 3D.",
+};
+
+export default function NotFound() {
+ return (
+
+
+ 404
+
+
+ Page not found
+
+
+ The page you're looking for doesn't exist or has been moved.
+
+
+ Back to Aeris
+
+
+ );
+}
diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx
new file mode 100644
index 0000000..96583c9
--- /dev/null
+++ b/src/app/opengraph-image.tsx
@@ -0,0 +1,148 @@
+import { ImageResponse } from "next/og";
+import { readFile } from "node:fs/promises";
+import { join } from "node:path";
+
+export const alt = "Aeris — Real-Time 3D Flight Tracking";
+export const size = { width: 1200, height: 630 };
+export const contentType = "image/png";
+
+export default async function Image() {
+ const imageData = await readFile(
+ join(process.cwd(), "public", "aeris-hero.png"),
+ );
+ const base64 = imageData.toString("base64");
+ const heroSrc = `data:image/png;base64,${base64}`;
+
+ return new ImageResponse(
+
+ {/* Hero background image */}
+

+
+ {/* Full dark vignette overlay */}
+
+
+ {/* Content overlay pinned to bottom */}
+
+ {/* Title */}
+
+ Aeris
+
+
+ {/* Tagline */}
+
+ Real-Time 3D Flight Tracking
+
+
+ {/* Divider + pills row */}
+
+ {["Altitude-Aware", "Live ADS-B Data", "Free & Open Source"].map(
+ (label) => (
+
+ {label}
+
+ ),
+ )}
+
+
+
+ {/* URL badge top-right */}
+
+ aeris.edbn.me
+
+
,
+ { ...size },
+ );
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 9349e85..ddd4cc9 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,17 +1,83 @@
import { FlightTracker } from "@/components/flight-tracker";
-const jsonLd = {
- "@context": "https://schema.org",
- "@type": "WebApplication",
- name: "Aeris",
- url: "https://aeris.edbn.me",
- description:
- "Track live flights in 3D over the world's busiest airspaces. Altitude-aware, beautifully rendered, and completely free.",
- applicationCategory: "TravelApplication",
- operatingSystem: "Any",
- offers: { "@type": "Offer", price: "0", priceCurrency: "USD" },
- author: { "@type": "Person", name: "kewonit" },
-};
+const siteUrl = "https://aeris.edbn.me";
+
+const jsonLd = [
+ {
+ "@context": "https://schema.org",
+ "@type": "WebApplication",
+ "@id": `${siteUrl}/#app`,
+ name: "Aeris",
+ url: siteUrl,
+ description:
+ "Track live flights in stunning 3D over the world's busiest airspaces. See real-time ADS-B data with altitude-aware rendering — low altitudes glow cyan, high altitudes shift to gold. Free and open source.",
+ applicationCategory: "TravelApplication",
+ operatingSystem: "Any",
+ browserRequirements: "Requires WebGL support",
+ offers: {
+ "@type": "Offer",
+ price: "0",
+ priceCurrency: "USD",
+ availability: "https://schema.org/OnlineOnly",
+ },
+ author: {
+ "@type": "Person",
+ name: "kewonit",
+ url: "https://github.com/kewonit",
+ },
+ featureList: [
+ "Real-time 3D flight tracking",
+ "Altitude-aware color rendering",
+ "Live ADS-B data from multiple sources",
+ "3D aircraft models",
+ "City-based airspace views",
+ "Live ATC audio streaming",
+ "Flight trail visualization",
+ "Aircraft photo lookup",
+ "Dark mode interface",
+ ],
+ screenshot:
+ "https://github.com/user-attachments/assets/9d1f50ed-be4e-4ef5-95ac-257e9129f8c8",
+ softwareVersion: "0.1.0",
+ isAccessibleForFree: true,
+ inLanguage: "en",
+ },
+ {
+ "@context": "https://schema.org",
+ "@type": "WebSite",
+ "@id": `${siteUrl}/#website`,
+ name: "Aeris",
+ url: siteUrl,
+ description:
+ "Real-time 3D flight tracking — altitude-aware, visually stunning, and completely free.",
+ inLanguage: "en",
+ publisher: {
+ "@type": "Person",
+ name: "kewonit",
+ url: "https://github.com/kewonit",
+ },
+ potentialAction: {
+ "@type": "SearchAction",
+ target: {
+ "@type": "EntryPoint",
+ urlTemplate: `${siteUrl}/?q={search_term_string}`,
+ },
+ "query-input": "required name=search_term_string",
+ },
+ },
+ {
+ "@context": "https://schema.org",
+ "@type": "BreadcrumbList",
+ itemListElement: [
+ {
+ "@type": "ListItem",
+ position: 1,
+ name: "Aeris — Real-Time 3D Flight Tracking",
+ item: siteUrl,
+ },
+ ],
+ },
+];
export default function Home() {
return (
diff --git a/src/app/robots.ts b/src/app/robots.ts
new file mode 100644
index 0000000..fa3cbd8
--- /dev/null
+++ b/src/app/robots.ts
@@ -0,0 +1,14 @@
+import type { MetadataRoute } from "next";
+
+export default function robots(): MetadataRoute.Robots {
+ return {
+ rules: [
+ {
+ userAgent: "*",
+ allow: "/",
+ disallow: ["/api/", "/private/"],
+ },
+ ],
+ sitemap: "https://aeris.edbn.me/sitemap.xml",
+ };
+}
diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts
new file mode 100644
index 0000000..48a17cd
--- /dev/null
+++ b/src/app/sitemap.ts
@@ -0,0 +1,12 @@
+import type { MetadataRoute } from "next";
+
+export default function sitemap(): MetadataRoute.Sitemap {
+ return [
+ {
+ url: "https://aeris.edbn.me",
+ lastModified: new Date(),
+ changeFrequency: "daily",
+ priority: 1,
+ },
+ ];
+}
diff --git a/src/app/twitter-image.tsx b/src/app/twitter-image.tsx
new file mode 100644
index 0000000..96583c9
--- /dev/null
+++ b/src/app/twitter-image.tsx
@@ -0,0 +1,148 @@
+import { ImageResponse } from "next/og";
+import { readFile } from "node:fs/promises";
+import { join } from "node:path";
+
+export const alt = "Aeris — Real-Time 3D Flight Tracking";
+export const size = { width: 1200, height: 630 };
+export const contentType = "image/png";
+
+export default async function Image() {
+ const imageData = await readFile(
+ join(process.cwd(), "public", "aeris-hero.png"),
+ );
+ const base64 = imageData.toString("base64");
+ const heroSrc = `data:image/png;base64,${base64}`;
+
+ return new ImageResponse(
+
+ {/* Hero background image */}
+

+
+ {/* Full dark vignette overlay */}
+
+
+ {/* Content overlay pinned to bottom */}
+
+ {/* Title */}
+
+ Aeris
+
+
+ {/* Tagline */}
+
+ Real-Time 3D Flight Tracking
+
+
+ {/* Divider + pills row */}
+
+ {["Altitude-Aware", "Live ADS-B Data", "Free & Open Source"].map(
+ (label) => (
+
+ {label}
+
+ ),
+ )}
+
+
+
+ {/* URL badge top-right */}
+
+ aeris.edbn.me
+
+
,
+ { ...size },
+ );
+}