Skip to content

Commit 1a1bc35

Browse files
committed
Add SEO: sitemap, Open Graph, JSON-LD, meta descriptions, and content strategy TODO
- Add @astrojs/sitemap for automatic sitemap generation - Add robots.txt pointing to sitemap - Add Open Graph and Twitter Card meta tags to all pages - Add per-page meta descriptions targeting relevant keywords - Add canonical URLs and hreflang alternate links for i18n - Add JSON-LD SoftwareApplication schema on download page - Add JSON-LD WebSite schema on home page - Add TODO.md with keyword strategy and blog content plan
1 parent 33a7011 commit 1a1bc35

10 files changed

Lines changed: 278 additions & 7 deletions

File tree

TODO.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# SEO Content Strategy — TODO
2+
3+
## 6. Keyword Optimization
4+
5+
### Target Keywords (by page)
6+
7+
**Home page** — primary landing page, should rank for:
8+
- "free projection mapping software"
9+
- "open source video mapping"
10+
- "projection mapping tool for artists"
11+
- "video mapping software free download"
12+
- "mapmap projection"
13+
14+
**Download page:**
15+
- "download projection mapping software free"
16+
- "video mapping software windows/mac/linux"
17+
18+
**Docs page:**
19+
- "projection mapping tutorial"
20+
- "how to use projection mapping software"
21+
- "video mapping beginner guide"
22+
23+
### Action Items
24+
25+
- [ ] Rewrite home page intro to naturally include target keywords (avoid stuffing — write for humans first, search engines second)
26+
- [ ] Add a "What is projection mapping?" section on the home page (targets informational queries, builds topical authority)
27+
- [ ] Ensure each page's H1 contains the primary keyword for that page
28+
- [ ] Add internal links between pages (e.g., docs page links to download, home links to docs)
29+
- [ ] Submit sitemap to Google Search Console
30+
- [ ] Submit sitemap to Bing Webmaster Tools
31+
- [ ] List MapMap on free software directories:
32+
- AlternativeTo.net
33+
- SourceForge
34+
- Free Software Directory (FSF)
35+
- awesome-projection-mapping lists on GitHub
36+
- FLOSS Manuals
37+
- [ ] Add the site to relevant "projection mapping software" comparison articles (reach out to authors)
38+
39+
## 7. Blog / Tutorials Section
40+
41+
### Why
42+
43+
- Fresh content signals authority to Google (active project = trustworthy)
44+
- Tutorials rank for long-tail queries ("how to projection map on a building", "mapmap osc tutorial")
45+
- Shareable content drives backlinks and social traffic
46+
- Artist showcases build community and social proof
47+
48+
### Implementation Plan
49+
50+
1. Add a blog content directory: `src/data/en/blog/` and `src/data/fr/blog/`
51+
2. Create a blog listing page at `/[locale]/blog/`
52+
3. Create a dynamic route for blog posts: `/[locale]/blog/[slug]/`
53+
4. Each post is a markdown file with frontmatter: title, date, description, tags, author
54+
5. Add blog link to navigation
55+
6. Add an RSS feed (Astro has `@astrojs/rss` for this — great for SEO and subscribers)
56+
57+
### Content Ideas (prioritized by SEO impact)
58+
59+
**High impact (targets search queries people actually make):**
60+
- [ ] "Getting Started with Projection Mapping: A Beginner's Guide"
61+
- [ ] "How to Set Up a Projection Mapping Installation for Live Events"
62+
- [ ] "Projection Mapping on Buildings: Step-by-Step Tutorial"
63+
- [ ] "Free Projection Mapping Software Comparison (2025)"
64+
- [ ] "How to Use OSC to Control Video Mapping in Real-Time"
65+
66+
**Medium impact (community building, shareable):**
67+
- [ ] Artist showcase: interview a MapMap user, feature their work
68+
- [ ] "MapMap at [Festival Name]: Recap and Photos"
69+
- [ ] "What's New in MapMap 0.6.3"
70+
- [ ] Video tutorials (embed YouTube/Vimeo — also good for video SEO)
71+
72+
**Low effort, ongoing:**
73+
- [ ] Release notes for each new version
74+
- [ ] Quick tips (under 300 words, one specific technique per post)
75+
76+
### Publishing Cadence
77+
78+
Aim for 1-2 posts per month. Consistency matters more than volume.
79+
Even a quarterly update post is better than silence.

astro.config.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { defineConfig } from 'astro/config';
22
import tailwind from '@astrojs/tailwind';
3+
import sitemap from '@astrojs/sitemap';
34

45
export default defineConfig({
56
site: 'https://mapmapteam.github.io',
6-
integrations: [tailwind()],
7+
integrations: [tailwind(), sitemap()],
78
i18n: {
89
defaultLocale: 'en',
910
locales: ['en', 'fr'],

package-lock.json

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"preview": "astro preview"
99
},
1010
"dependencies": {
11+
"@astrojs/sitemap": "^3.7.2",
1112
"@astrojs/tailwind": "^6.0.0",
1213
"@tailwindcss/typography": "^0.5.19",
1314
"astro": "^5.0.0",

public/robots.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
User-agent: *
2+
Allow: /
3+
4+
Sitemap: https://mapmapteam.github.io/sitemap-index.xml

src/layouts/BaseLayout.astro

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
---
22
import Navigation from '../components/Navigation.astro';
33
import Footer from '../components/Footer.astro';
4-
import { getLangFromUrl } from '../i18n/utils';
4+
import { getLangFromUrl, getLocalizedPath } from '../i18n/utils';
5+
import { languages } from '../i18n/ui';
6+
import type { Locale } from '../i18n/utils';
57
68
interface Props {
79
title: string;
810
description?: string;
11+
ogImage?: string;
12+
jsonLd?: Record<string, unknown>;
913
}
1014
11-
const { title, description = 'MapMap - open source video mapping software' } = Astro.props;
15+
const {
16+
title,
17+
description = 'MapMap is a free, open source projection mapping software for artists and creative teams. Available on Windows, macOS, and Linux.',
18+
ogImage = 'http://projection-mapping.org/wp-content/uploads/2017/08/mapmap-workshop.jpg',
19+
jsonLd,
20+
} = Astro.props;
21+
1222
const lang = getLangFromUrl(Astro.url);
23+
const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
24+
const currentPath = Astro.url.pathname;
1325
---
1426

1527
<!doctype html>
@@ -20,6 +32,43 @@ const lang = getLangFromUrl(Astro.url);
2032
<meta name="description" content={description} />
2133
<title>{title} | MapMap</title>
2234
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
35+
36+
<!-- Canonical URL -->
37+
<link rel="canonical" href={canonicalUrl.href} />
38+
39+
<!-- Alternate language links -->
40+
{Object.keys(languages).map((code) => (
41+
<link
42+
rel="alternate"
43+
hreflang={code}
44+
href={new URL(getLocalizedPath(currentPath, code as Locale), Astro.site).href}
45+
/>
46+
))}
47+
<link
48+
rel="alternate"
49+
hreflang="x-default"
50+
href={new URL(getLocalizedPath(currentPath, 'en'), Astro.site).href}
51+
/>
52+
53+
<!-- Open Graph -->
54+
<meta property="og:type" content="website" />
55+
<meta property="og:url" content={canonicalUrl.href} />
56+
<meta property="og:title" content={`${title} | MapMap`} />
57+
<meta property="og:description" content={description} />
58+
<meta property="og:image" content={ogImage} />
59+
<meta property="og:locale" content={lang === 'fr' ? 'fr_FR' : 'en_US'} />
60+
<meta property="og:site_name" content="MapMap" />
61+
62+
<!-- Twitter Card -->
63+
<meta name="twitter:card" content="summary_large_image" />
64+
<meta name="twitter:title" content={`${title} | MapMap`} />
65+
<meta name="twitter:description" content={description} />
66+
<meta name="twitter:image" content={ogImage} />
67+
68+
<!-- JSON-LD Structured Data -->
69+
{jsonLd && (
70+
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />
71+
)}
2372
</head>
2473
<body class="min-h-screen flex flex-col bg-white text-gray-900">
2574
<Navigation />

src/pages/[locale]/docs.astro

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,17 @@ const lang = getLangFromUrl(Astro.url);
1010
1111
const content = await import(`../../data/${lang}/docs.md`);
1212
const Content = content.default;
13+
14+
const descriptions = {
15+
en: 'Learn how to use MapMap: projection mapping tutorial covering layers, shapes, meshes, OSC control, and more. Complete user guide for beginners and advanced users.',
16+
fr: 'Apprenez à utiliser MapMap : tutoriel de projection vidéo couvrant les calques, formes, meshes, contrôle OSC et plus. Guide complet pour débutants et utilisateurs avancés.',
17+
};
1318
---
1419

15-
<BaseLayout title="Documentation">
20+
<BaseLayout
21+
title="Documentation"
22+
description={descriptions[lang]}
23+
>
1624
<article class="prose prose-lg max-w-none">
1725
<Content />
1826
</article>

src/pages/[locale]/download.astro

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,42 @@ const lang = getLangFromUrl(Astro.url);
1010
1111
const content = await import(`../../data/${lang}/download.md`);
1212
const Content = content.default;
13+
14+
const descriptions = {
15+
en: 'Download MapMap for free — open source projection mapping software for Windows, macOS, and Linux. No registration required. Start video mapping in minutes.',
16+
fr: 'Téléchargez MapMap gratuitement — logiciel libre de projection vidéo pour Windows, macOS et Linux. Aucune inscription requise. Commencez le video mapping en quelques minutes.',
17+
};
18+
19+
const jsonLd = {
20+
'@context': 'https://schema.org',
21+
'@type': 'SoftwareApplication',
22+
name: 'MapMap',
23+
description: descriptions[lang],
24+
url: 'https://mapmapteam.github.io',
25+
applicationCategory: 'MultimediaApplication',
26+
operatingSystem: 'Windows, macOS, Linux',
27+
offers: {
28+
'@type': 'Offer',
29+
price: '0',
30+
priceCurrency: 'USD',
31+
},
32+
license: 'https://opensource.org/licenses/GPL-3.0',
33+
softwareVersion: '0.6.3',
34+
downloadUrl: 'http://download.mapmap.info/windows/mapmap-0.6.3-x86-installer.exe',
35+
screenshot: 'http://projection-mapping.org/wp-content/uploads/2017/08/mapmap-workshop.jpg',
36+
author: {
37+
'@type': 'Organization',
38+
name: 'MapMap Team',
39+
url: 'https://mapmapteam.github.io',
40+
},
41+
};
1342
---
1443

15-
<BaseLayout title={lang === 'fr' ? 'Télécharger' : 'Download'}>
44+
<BaseLayout
45+
title={lang === 'fr' ? 'Télécharger' : 'Download'}
46+
description={descriptions[lang]}
47+
jsonLd={jsonLd}
48+
>
1649
<article class="prose prose-lg max-w-none">
1750
<Content />
1851
</article>

src/pages/[locale]/index.astro

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,27 @@ const lang = getLangFromUrl(Astro.url);
1010
1111
const content = await import(`../../data/${lang}/home.md`);
1212
const Content = content.default;
13+
14+
const descriptions = {
15+
en: 'MapMap is a free, open source projection mapping software for artists and small teams. Create stunning video projections on any surface. Download for Windows, macOS, and Linux.',
16+
fr: 'MapMap est un logiciel libre et gratuit de projection vidéo (video mapping) pour artistes et petites équipes. Créez des projections visuelles sur toute surface. Disponible sur Windows, macOS et Linux.',
17+
};
18+
19+
const jsonLd = {
20+
'@context': 'https://schema.org',
21+
'@type': 'WebSite',
22+
name: 'MapMap',
23+
url: 'https://mapmapteam.github.io',
24+
description: descriptions[lang],
25+
inLanguage: lang,
26+
};
1327
---
1428

15-
<BaseLayout title={lang === 'fr' ? 'Accueil' : 'Home'}>
29+
<BaseLayout
30+
title={lang === 'fr' ? 'Accueil' : 'Home'}
31+
description={descriptions[lang]}
32+
jsonLd={jsonLd}
33+
>
1634
<article class="prose prose-lg max-w-none">
1735
<Content />
1836
</article>

0 commit comments

Comments
 (0)