Skip to content

Commit 285fdf3

Browse files
committed
Add SEO, social meta, and the AM logo
New brand mark: "AM" in the wordmark's Noto Sans JP bold on the primary blue, generated at every needed size (favicon, 192/512 app icons, apple-touch, and a 1200x630 Open Graph card) and shown beside the wordmark in the desktop and mobile headers. SEO layer: meta description, Open Graph + Twitter card tags, canonical URL, theme-color, WebApplication JSON-LD, web manifest, robots.txt, and a sitemap. A SeoService keeps description/OG/canonical in sync with the active route from per-route data; the production origin lives in one config constant for an easy custom-domain swap later. 2 new e2e specs (35 total).
1 parent 5687166 commit 285fdf3

19 files changed

Lines changed: 242 additions & 11 deletions

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<p align="center"><img src="public/icon-192.png" width="96" alt="AniMatch logo"></p>
2+
13
<h1 align="center">AniMatch</h1>
24

35
Compare anime taste between [AniList](https://anilist.co) users. One place that answers: **how compatible are we, where do we disagree, and what should we watch together?**

e2e/seo.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { expect, test } from '@playwright/test';
2+
3+
test('meta description, canonical, and og:url track the route', async ({ page }) => {
4+
await page.goto('/backlog');
5+
await expect(page).toHaveTitle(/Shared backlog AniMatch/);
6+
await expect(page.locator('meta[name="description"]')).toHaveAttribute(
7+
'content',
8+
/plan-to-watch lists/,
9+
);
10+
await expect(page.locator('link[rel="canonical"]')).toHaveAttribute('href', /\/backlog$/);
11+
await expect(page.locator('meta[property="og:url"]')).toHaveAttribute('content', /\/backlog$/);
12+
13+
// navigating updates the tags
14+
await page
15+
.getByRole('navigation', { name: 'Global navigation' })
16+
.getByRole('link', { name: 'Groups' })
17+
.click();
18+
await expect(page.locator('meta[name="description"]')).toHaveAttribute('content', /watch club/);
19+
await expect(page.locator('link[rel="canonical"]')).toHaveAttribute('href', /\/groups$/);
20+
});
21+
22+
test('social cards and icons are declared', async ({ page }) => {
23+
await page.goto('/');
24+
await expect(page.locator('meta[property="og:image"]')).toHaveAttribute('content', /og-image\.png$/);
25+
await expect(page.locator('meta[name="twitter:card"]')).toHaveAttribute('content', 'summary_large_image');
26+
await expect(page.locator('link[rel="manifest"]')).toHaveAttribute('href', 'site.webmanifest');
27+
await expect(page.locator('link[rel="icon"][sizes="32x32"]')).toHaveAttribute('href', 'favicon-32.png');
28+
await expect(page.locator('script[type="application/ld+json"]')).toHaveCount(1);
29+
});

public/apple-touch-icon.png

3 KB
Loading

public/favicon-32.png

709 Bytes
Loading

public/favicon.ico

-14.7 KB
Binary file not shown.

public/icon-192.png

4.63 KB
Loading

public/icon-512.png

13.2 KB
Loading

public/og-image.png

34.2 KB
Loading

public/robots.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
User-agent: *
2+
Allow: /
3+
Disallow: /auth/
4+
5+
Sitemap: https://animatch-hazels-projects-ebc086d4.vercel.app/sitemap.xml

public/site.webmanifest

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "AniMatch",
3+
"short_name": "AniMatch",
4+
"description": "Compare AniList profiles to see how compatible your anime taste is and what to watch together.",
5+
"start_url": "/",
6+
"display": "standalone",
7+
"background_color": "#f4f5f7",
8+
"theme_color": "#0f57c2",
9+
"icons": [
10+
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
11+
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
12+
]
13+
}

0 commit comments

Comments
 (0)