Skip to content

Commit f3e5ca1

Browse files
authored
Merge pull request #11 from intellica-tech/feat/gamification-phase1
Feat i18n and gamifications
2 parents 1d0345f + a6bb6ee commit f3e5ca1

130 files changed

Lines changed: 29859 additions & 15999 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docker.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
build-and-push:
1515
name: Build & Push Docker Image
1616
runs-on: ubuntu-latest
17+
timeout-minutes: 15
1718

1819
# Required permissions for GHCR
1920
permissions:
@@ -24,15 +25,15 @@ jobs:
2425
steps:
2526
# ── 1. Checkout ────────────────────────────────────────────────────────
2627
- name: Checkout repository
27-
uses: actions/checkout@v4
28+
uses: actions/checkout@v6
2829

2930
# ── 2. Set up Docker Buildx (multi-platform + cache support) ──────────
3031
- name: Set up Docker Buildx
31-
uses: docker/setup-buildx-action@v3
32+
uses: docker/setup-buildx-action@v4
3233

3334
# ── 3. Log in to GHCR ──────────────────────────────────────────────────
3435
- name: Log in to GitHub Container Registry
35-
uses: docker/login-action@v3
36+
uses: docker/login-action@v4
3637
with:
3738
registry: ${{ env.REGISTRY }}
3839
username: ${{ github.actor }}
@@ -41,7 +42,7 @@ jobs:
4142
# ── 4. Extract metadata (tags & labels) ───────────────────────────────
4243
- name: Extract Docker metadata
4344
id: meta
44-
uses: docker/metadata-action@v5
45+
uses: docker/metadata-action@v6
4546
with:
4647
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
4748
tags: |
@@ -55,7 +56,7 @@ jobs:
5556
# ── 5. Build and push ─────────────────────────────────────────────────
5657
- name: Build and push Docker image
5758
id: push
58-
uses: docker/build-push-action@v6
59+
uses: docker/build-push-action@v7
5960
with:
6061
context: .
6162
push: true

.github/workflows/pages.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,24 @@ jobs:
2525
build:
2626
name: Build Astro Site
2727
runs-on: ubuntu-latest
28+
timeout-minutes: 10
2829

2930
steps:
3031
# ── 1. Checkout ──────────────────────────────────────────────────────────
3132
- name: Checkout repository
32-
uses: actions/checkout@v4
33+
uses: actions/checkout@v6
3334

3435
# ── 2. Setup Node.js ─────────────────────────────────────────────────────
3536
- name: Setup Node.js
36-
uses: actions/setup-node@v4
37+
uses: actions/setup-node@v6
3738
with:
38-
node-version: '22'
39+
node-version: '24'
3940
cache: 'npm'
4041

4142
# ── 3. Setup GitHub Pages (writes correct base path etc.) ────────────────
4243
- name: Setup GitHub Pages
4344
id: pages
44-
uses: actions/configure-pages@v5
45+
uses: actions/configure-pages@v6
4546

4647
# ── 4. Install dependencies ───────────────────────────────────────────────
4748
- name: Install dependencies
@@ -56,7 +57,7 @@ jobs:
5657

5758
# ── 6. Upload artifact for Pages ─────────────────────────────────────────
5859
- name: Upload Pages artifact
59-
uses: actions/upload-pages-artifact@v3
60+
uses: actions/upload-pages-artifact@v4
6061
with:
6162
path: ./dist
6263

@@ -65,6 +66,7 @@ jobs:
6566
name: Deploy to GitHub Pages
6667
needs: build
6768
runs-on: ubuntu-latest
69+
timeout-minutes: 5
6870

6971
environment:
7072
name: github-pages
@@ -73,7 +75,7 @@ jobs:
7375
steps:
7476
- name: Deploy to GitHub Pages
7577
id: deployment
76-
uses: actions/deploy-pages@v4
78+
uses: actions/deploy-pages@v5
7779

7880
# ── Summary ────────────────────────────────────────────────────────────
7981
- name: Write job summary

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ pnpm-debug.log*
3333
.claude/settings.local.json
3434
.claude/todos/
3535

36+
.superpowers/brainstorm/
37+
.playwright-mcp/

astro.config.mjs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
1-
// @ts-check
21
import { defineConfig } from 'astro/config';
32
import sitemap from '@astrojs/sitemap';
43

5-
// https://astro.build/config
64
export default defineConfig({
75
site: 'https://intellica.net',
86
output: 'static',
9-
integrations: [sitemap()],
7+
i18n: {
8+
locales: ['en', 'tr'],
9+
defaultLocale: 'en',
10+
routing: {
11+
prefixDefaultLocale: false,
12+
},
13+
},
14+
integrations: [
15+
sitemap({
16+
i18n: {
17+
defaultLocale: 'en',
18+
locales: {
19+
en: 'en-US',
20+
tr: 'tr-TR',
21+
},
22+
},
23+
}),
24+
],
25+
redirects: {
26+
'/about-us': '/about',
27+
'/our-products': '/products',
28+
'/our-services': '/solutions',
29+
'/career': '/careers',
30+
'/privacy-policy': '/privacy',
31+
'/cookie-policy': '/cookies',
32+
'/terms-and-conditions': '/terms',
33+
'/blog': '/insights',
34+
'/business-benefits': '/solutions',
35+
'/demo': '/contact',
36+
'/tr/about-us': '/tr/about',
37+
'/tr/our-products': '/tr/products',
38+
'/tr/our-services': '/tr/solutions',
39+
'/tr/career': '/tr/careers',
40+
'/tr/business-benefits': '/tr/solutions',
41+
'/tr/privacy-policy': '/tr/privacy',
42+
'/tr/cookie-policy': '/tr/cookies',
43+
},
1044
});

docs/i18n-research-2026.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# Multi-Language Research — Astro 6 + SEO Best Practices 2026
2+
3+
> Date: 2026-04-08
4+
> Astro Version: 6.1.5 (upgraded from 5.17.1)
5+
6+
## Industry Consensus: Subdirectory Approach
7+
8+
All major sources agree — subdirectory (`/tr/`, `/de/`) is the standard for 85%+ of websites.
9+
10+
| Source | Recommendation |
11+
|---|---|
12+
| Google Search Central | Subdirectory for unified authority |
13+
| Next.js App Router | `[locale]/` dynamic segment |
14+
| Astro 6 | `src/pages/{locale}/` folder structure |
15+
| Vercel | Subdirectory for SEO-optimized sites |
16+
| SEO Industry (2026) | Subdirectory dominates |
17+
18+
### Why Subdirectory Wins
19+
- Domain authority consolidation (backlinks benefit all languages)
20+
- Single Google Search Console property
21+
- Low maintenance (one hosting, one SSL, one deploy)
22+
- Easy hreflang management
23+
24+
### Google Critical Warnings
25+
1. **"Avoid automatically redirecting users from one language version to another"** — harmful for both users and crawlers
26+
2. **"Don't use IP analysis to adapt your content"** — unreliable
27+
3. Google uses **visible page content** to determine language, not `lang` attribute or URL
28+
4. Recommend **hyperlinks to other language versions** for user choice
29+
30+
## Astro 6 Native i18n System
31+
32+
### Configuration (`astro.config.mjs`)
33+
34+
```javascript
35+
export default defineConfig({
36+
site: 'https://intellica.net',
37+
output: 'static',
38+
i18n: {
39+
locales: ['en', 'tr'],
40+
defaultLocale: 'en',
41+
routing: {
42+
prefixDefaultLocale: false, // EN at /, TR at /tr/
43+
},
44+
fallback: {
45+
tr: 'en' // Missing TR pages fall back to EN
46+
}
47+
},
48+
integrations: [
49+
sitemap({
50+
i18n: {
51+
defaultLocale: 'en',
52+
locales: { en: 'en-US', tr: 'tr-TR' },
53+
},
54+
}),
55+
],
56+
});
57+
```
58+
59+
### File Structure
60+
61+
```
62+
src/pages/
63+
index.astro → intellica.net/
64+
about.astro → intellica.net/about/
65+
products.astro → intellica.net/products/
66+
tr/
67+
index.astro → intellica.net/tr/
68+
about.astro → intellica.net/tr/about/
69+
products.astro → intellica.net/tr/products/
70+
```
71+
72+
### Helper Functions (`astro:i18n`)
73+
74+
```javascript
75+
import {
76+
getRelativeLocaleUrl, // getRelativeLocaleUrl('tr', 'about') → '/tr/about'
77+
getAbsoluteLocaleUrl, // Full URL with domain
78+
getRelativeLocaleUrlList, // All locale variants for a path
79+
getLocaleByPath, // Extract locale from URL path
80+
} from 'astro:i18n';
81+
```
82+
83+
### Page-level Locale Access
84+
85+
- `Astro.currentLocale` — Works in static. Returns locale from URL or defaultLocale.
86+
- `Astro.preferredLocale` — SSR only. NOT available in static builds.
87+
- `Astro.preferredLocaleList` — SSR only.
88+
89+
### Translation System (Official Recipe)
90+
91+
```typescript
92+
// src/i18n/ui.ts
93+
export const ui = {
94+
en: { 'nav.home': 'Home', 'nav.about': 'About' },
95+
tr: { 'nav.home': 'Ana Sayfa', 'nav.about': 'Hakkımızda' },
96+
} as const;
97+
98+
// src/i18n/utils.ts
99+
export function getLangFromUrl(url: URL) { ... }
100+
export function useTranslations(lang) { ... }
101+
export function useTranslatedPath(lang) { ... }
102+
```
103+
104+
### SEO: hreflang Tags
105+
106+
```html
107+
<link rel="alternate" hreflang="en" href="https://intellica.net/about" />
108+
<link rel="alternate" hreflang="tr" href="https://intellica.net/tr/about" />
109+
<link rel="alternate" hreflang="x-default" href="https://intellica.net/about" />
110+
```
111+
112+
### Sitemap: Automatic hreflang XML
113+
114+
`@astrojs/sitemap` with i18n config auto-generates:
115+
```xml
116+
<url>
117+
<loc>https://intellica.net/about/</loc>
118+
<xhtml:link rel="alternate" hreflang="en-US" href="https://intellica.net/about/"/>
119+
<xhtml:link rel="alternate" hreflang="tr-TR" href="https://intellica.net/tr/about/"/>
120+
</url>
121+
```
122+
123+
### Astro 6 Breaking Change
124+
- `redirectToDefaultLocale` default changed from `true` (v5) to `false` (v6)
125+
- Requires `prefixDefaultLocale: true` to function
126+
- Not relevant if using `prefixDefaultLocale: false`
127+
128+
## Browser Language Detection — Static Site Limitations
129+
130+
`Astro.preferredLocale` is SSR-only. For static sites, options:
131+
132+
1. **Client-side JS** — Read `navigator.language`, show banner (NOT redirect)
133+
2. **Language switcher in header** — Always visible toggle
134+
3. **Combination** — Toggle always present + soft banner for detected language mismatch
135+
136+
Google recommends option 2+3: **always provide a language switcher, optionally suggest based on browser language, never force redirect.**
137+
138+
## Third-Party Libraries — Not Recommended
139+
140+
| Library | Status (2026) |
141+
|---|---|
142+
| astro-i18next | Abandoned, Astro 5 incompatible |
143+
| astro-i18n-aut | Inactive 1+ year |
144+
| Paraglide JS | SSR only, not for static |
145+
| **Astro built-in** | **Stable, recommended** |
146+
147+
## Current Site State
148+
149+
- All content hardcoded in .astro files (no content collections)
150+
- No existing i18n infrastructure
151+
- Organization schema already declares `availableLanguage: ["English", "Turkish"]`
152+
- Navigation links hardcoded as arrays in Header/Footer/BottomNav components
153+
- 34 pages, static output, GitHub Pages deploy
154+
155+
## Key Decisions Needed
156+
157+
1. Default language: EN (preserves current Google index) vs TR (company is Turkish)
158+
2. Content extraction: How to organize translation strings
159+
3. Browser detection: Banner vs redirect vs toggle-only
160+
4. Page duplication: Full duplicate pages vs shared templates with translated content
161+
5. Redirect strategy: Old `/tr/*` URLs → new `/tr/*` URLs

0 commit comments

Comments
 (0)