@lightupai/polaris 0.0.59 → 0.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +1 -0
- package/deploy.sh +1 -0
- package/docker/Caddyfile +2 -0
- package/docs/seo-geo.md +17 -14
- package/favicon.svg +10 -0
- package/package.json +1 -1
- package/scripts/seo-audit.ts +2 -2
- package/src/web/app.ts +9 -0
- package/src/web/layout.ts +1 -0
package/.github/workflows/ci.yml
CHANGED
|
@@ -91,5 +91,6 @@ jobs:
|
|
|
91
91
|
git pull --ff-only &&
|
|
92
92
|
docker compose -f docker-compose.prod.yml build &&
|
|
93
93
|
docker compose -f docker-compose.prod.yml up -d --remove-orphans &&
|
|
94
|
+
docker compose -f docker-compose.prod.yml exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null || true &&
|
|
94
95
|
docker compose -f docker-compose.prod.yml ps
|
|
95
96
|
"
|
package/deploy.sh
CHANGED
|
@@ -12,6 +12,7 @@ ssh "$USER@$HOST" "
|
|
|
12
12
|
git pull --ff-only &&
|
|
13
13
|
docker compose -f docker-compose.prod.yml build &&
|
|
14
14
|
docker compose -f docker-compose.prod.yml up -d --remove-orphans &&
|
|
15
|
+
docker compose -f docker-compose.prod.yml exec caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null || true &&
|
|
15
16
|
docker compose -f docker-compose.prod.yml ps
|
|
16
17
|
"
|
|
17
18
|
|
package/docker/Caddyfile
CHANGED
package/docs/seo-geo.md
CHANGED
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
- [x] **sitemap.xml** — lists the landing page
|
|
12
12
|
- [x] **Cloudflare DNS** — domain managed on Cloudflare with MX + SPF records
|
|
13
13
|
- [x] **Email routing** — `*@withpolaris.ai` forwards to `support@lightup.ai`
|
|
14
|
+
- [x] **Self-host Tailwind CSS** — replaced 127KB CDN script with purged 26KB static CSS (5.5KB gzip). Production Lighthouse: score 84→99, FCP 3.4s→1.6s, page weight 175KB→77KB
|
|
15
|
+
- [x] **Lighthouse performance audit** — `make perf` runs mobile+desktop against prod and local, checks Google "good" budgets (score≥90, FCP≤1.8s, LCP≤2.5s), saves JSON to `docs/audits/`
|
|
16
|
+
- [x] **DataForSEO on-page audit** — `make seo` runs 20 SEO checks via DataForSEO API, saves JSON to `docs/audits/`
|
|
17
|
+
- [x] **Heading hierarchy** — verified: 1×h1, 7×h2, 18×h3, proper structure (DataForSEO score 100/100)
|
|
14
18
|
|
|
15
19
|
## SEO — To Do
|
|
16
20
|
|
|
@@ -27,10 +31,13 @@
|
|
|
27
31
|
- Cloudflare Web Analytics (free, built into Cloudflare dashboard)
|
|
28
32
|
Add the tracking script to the layout.
|
|
29
33
|
|
|
30
|
-
- [ ] **
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
- [ ] **Favicon**
|
|
35
|
+
No favicon set. Flagged by DataForSEO audit. Add one for browser tabs and bookmarks.
|
|
36
|
+
Use the Polaris hub icon or a simplified version.
|
|
37
|
+
|
|
38
|
+
- [ ] **Enable gzip/brotli compression**
|
|
39
|
+
DataForSEO flagged `no_content_encoding`. Caddy should be compressing responses.
|
|
40
|
+
Add `encode gzip zstd` to the Caddyfile.
|
|
34
41
|
|
|
35
42
|
### Medium Priority
|
|
36
43
|
|
|
@@ -61,15 +68,11 @@
|
|
|
61
68
|
- "Gong for AI coding"
|
|
62
69
|
Options: simple `/blog` route with markdown rendering, or a subdomain `blog.withpolaris.ai`.
|
|
63
70
|
|
|
64
|
-
- [ ] **Heading hierarchy audit**
|
|
65
|
-
Ensure proper h1 → h2 → h3 structure on the landing page.
|
|
66
|
-
Only one h1 per page. Check that section headers use correct levels.
|
|
67
|
-
|
|
68
71
|
### Low Priority
|
|
69
72
|
|
|
70
|
-
- [ ] **
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
- [ ] **Improve content rate**
|
|
74
|
+
DataForSEO flagged text at 8.2% of page HTML (want ≥10%).
|
|
75
|
+
More copy or blog content will fix this.
|
|
73
76
|
|
|
74
77
|
- [ ] **404 page**
|
|
75
78
|
Custom 404 page with navigation back to the landing page.
|
|
@@ -108,9 +111,9 @@
|
|
|
108
111
|
- Or relying on Cloudflare proxy to cache static content at edge
|
|
109
112
|
|
|
110
113
|
- [ ] **Cache headers for static assets**
|
|
111
|
-
OG image has 24h cache. Landing page HTML
|
|
112
|
-
|
|
113
|
-
changes infrequently.
|
|
114
|
+
OG image has 24h cache. CSS has immutable 1yr cache. Landing page HTML
|
|
115
|
+
has `Cache-Control: no-store` — consider short cache (5-10 min) since
|
|
116
|
+
it changes infrequently.
|
|
114
117
|
|
|
115
118
|
### Low Priority
|
|
116
119
|
|
package/favicon.svg
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
2
|
+
<circle cx="16" cy="16" r="14" fill="#4c6ef5"/>
|
|
3
|
+
<circle cx="16" cy="16" r="4" fill="white"/>
|
|
4
|
+
<circle cx="16" cy="6" r="2.5" fill="white"/>
|
|
5
|
+
<circle cx="24.7" cy="21" r="2.5" fill="white"/>
|
|
6
|
+
<circle cx="7.3" cy="21" r="2.5" fill="white"/>
|
|
7
|
+
<line x1="16" y1="12" x2="16" y2="8.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
|
8
|
+
<line x1="19.5" y1="18" x2="22.5" y2="19.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
|
9
|
+
<line x1="12.5" y1="18" x2="9.5" y2="19.5" stroke="white" stroke-width="1.5" stroke-linecap="round"/>
|
|
10
|
+
</svg>
|
package/package.json
CHANGED
package/scripts/seo-audit.ts
CHANGED
|
@@ -118,8 +118,8 @@ check("Desc/content match", content.description_to_content_consistency >= 0.8,
|
|
|
118
118
|
|
|
119
119
|
// Technical
|
|
120
120
|
check("Favicon", !checks.no_favicon, checks.no_favicon ? "missing" : "present");
|
|
121
|
-
check("No render-blocking",
|
|
122
|
-
|
|
121
|
+
check("No render-blocking scripts", (meta.render_blocking_scripts_count ?? 0) === 0,
|
|
122
|
+
(meta.render_blocking_scripts_count ?? 0) === 0 ? "clean" : `${meta.render_blocking_scripts_count} script(s)`);
|
|
123
123
|
check("Content encoding", !checks.no_content_encoding,
|
|
124
124
|
checks.no_content_encoding ? "no gzip/brotli" : "enabled");
|
|
125
125
|
check("SEO-friendly URL", !!checks.seo_friendly_url, checks.seo_friendly_url ? "yes" : "no");
|
package/src/web/app.ts
CHANGED
|
@@ -149,6 +149,15 @@ export function createApp(sql: Sql) {
|
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
|
|
152
|
+
app.get("/favicon.svg", async (c) => {
|
|
153
|
+
const file = Bun.file(new URL("../../favicon.svg", import.meta.url).pathname);
|
|
154
|
+
return new Response(await file.arrayBuffer(), {
|
|
155
|
+
headers: { "Content-Type": "image/svg+xml", "Cache-Control": "public, max-age=31536000, immutable" },
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
app.get("/favicon.ico", (c) => c.redirect("/favicon.svg", 301));
|
|
160
|
+
|
|
152
161
|
// --- SEO ---
|
|
153
162
|
|
|
154
163
|
app.get("/og-image.png", async (c) => {
|
package/src/web/layout.ts
CHANGED
|
@@ -37,6 +37,7 @@ export function layout(body: string, title = "Polaris", seo?: SeoOpts): Response
|
|
|
37
37
|
<meta name="twitter:title" content="${pageTitle}">
|
|
38
38
|
<meta name="twitter:description" content="${description}">
|
|
39
39
|
<meta name="twitter:image" content="${ogImage}">
|
|
40
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
40
41
|
<link rel="stylesheet" href="/styles.css">
|
|
41
42
|
</head>
|
|
42
43
|
<body class="bg-gray-50 text-gray-900 antialiased"><div class="overflow-x-hidden max-w-[100vw]">${body}</div>
|