# Frontend (Next.js) — Site Ayarları Entegrasyonu
## Genel Bakış
Backend'den tüm site ayarları **tek bir API çağrısı** ile alınır. Ayarlar gruplara ayrılmış nested JSON formatında gelir. Bu veri layout, header, footer, SEO meta tag'leri, analytics scriptleri ve tüm sabit içerikleri besler.
**Sensitive key'ler (API key, secret, password) public endpoint'ten filtrelenmiştir — güvenle kullanabilirsin.**
---
## API Endpoints (Public — Auth Yok)
| Method | Endpoint | Açıklama |
|--------|----------|----------|
| `GET` | `/api/v1/settings` | Tüm public ayarlar (grouped nested JSON) |
| `GET` | `/api/v1/settings/{group}` | Tek grup ayarları (flat key-value) |
---
## GET /api/v1/settings — Response Formatı
```json
{
"general": {
"site_name": "Boğaziçi Denizcilik Eğitim Kurumu",
"site_tagline": "Türkiye'nin Köklü Denizcilik Okulu",
"site_description": "Türkiye'nin köklü denizcilik eğitim kurumu",
"logo_light": "/storage/uploads/logo-white.png",
"logo_dark": "/storage/uploads/logo-dark.png",
"favicon": "/storage/uploads/favicon.png",
"apple_touch_icon": null,
"announcement_bar_active": "true",
"announcement_bar_text": "2026 Kayıtları Devam Ediyor",
"announcement_bar_url": "/kayit",
"announcement_bar_bg_color": "#1a3e74",
"maintenance_mode": "false",
"maintenance_message": "Sitemiz bakımdadır, kısa süre içinde geri döneceğiz."
},
"contact": {
"phone_primary": "+90 532 724 15 32",
"phone_secondary": null,
"email_info": "bilgi@bogazicidenizcilik.com",
"address_full": "Osmanağa Mah. Çuhadarağa Sk. No:21 Kadıköy/İstanbul",
"address_short": "Kadıköy, İstanbul",
"working_hours_weekday": "Hafta İçi 09:00 – 17:00",
"whatsapp_number": null,
"whatsapp_message": "Merhaba, bilgi almak istiyorum."
},
"maps": {
"google_maps_embed_url": null,
"google_maps_place_url": null,
"latitude": "40.9876",
"longitude": "29.0234",
"map_zoom_level": "15"
},
"social": {
"instagram_url": null,
"instagram_handle": null,
"facebook_url": null,
"youtube_url": null,
"linkedin_url": null,
"tiktok_url": null,
"twitter_url": null
},
"seo": {
"meta_title_suffix": "| Boğaziçi Denizcilik",
"meta_title_separator": "|",
"default_meta_description": "IMO ve STCW standartlarında denizcilik eğitimi.",
"default_meta_keywords": "denizcilik kursu, STCW eğitimi, kaptan kursu",
"robots": "index, follow",
"canonical_domain": "https://bogazicidenizcilik.com",
"og_image": null,
"og_type": "website",
"og_locale": "tr_TR",
"og_site_name": "Boğaziçi Denizcilik",
"twitter_card_type": "summary_large_image",
"google_site_verification": null
},
"analytics": {
"google_analytics_id": null,
"google_tag_manager_id": null,
"facebook_pixel_id": null,
"hotjar_id": null,
"clarity_id": null,
"crisp_website_id": null,
"custom_head_scripts": null,
"custom_body_scripts": null
},
"header": {
"navbar_style_default": "transparent",
"cta_button_text": "Başvuru Yap",
"cta_button_url": "/kayit",
"cta_button_color": "#396cab",
"show_phone_topbar": "true",
"show_email_topbar": "true",
"show_address_topbar": "true",
"show_hours_topbar": "true",
"show_social_navbar": "true"
},
"footer": {
"footer_description": "Türkiye'nin köklü denizcilik eğitim kurumlarından biri olarak...",
"footer_logo": null,
"copyright_text": "© 2026 Boğaziçi Denizcilik Eğitim Kurumu. Tüm hakları saklıdır.",
"footer_address": "Osmanağa Bahariye Cad. No:31 Kadıköy/İstanbul",
"footer_phone": "+90 532 724 15 32",
"footer_email": "bilgi@bogazicidenizcilik.com",
"footer_bg_color": "#0f2447",
"show_social_footer": "true"
}
}
```
> **Not:** `integrations` grubu public API'den dönmez (tamamı `is_public: false`). `maps.google_maps_api_key` de filtrelenmiştir.
---
## GET /api/v1/settings/{group} — Tek Grup
```
GET /api/v1/settings/contact
```
```json
{
"phone_primary": "+90 532 724 15 32",
"email_info": "bilgi@bogazicidenizcilik.com",
"address_full": "Osmanağa Mah. Çuhadarağa Sk. No:21 Kadıköy/İstanbul",
...
}
```
Geçerli group değerleri: `general`, `contact`, `maps`, `social`, `seo`, `analytics`, `header`, `footer`
---
## Önerilen Veri Akışı (Next.js)
### 1. Layout-Level Fetch (Server Component)
Ayarlar tüm sayfalarda gerekli (header, footer, SEO). Layout'ta bir kez fetch edip context/provider ile dağıt:
```tsx
// app/layout.tsx
async function getSettings() {
const res = await fetch(`${process.env.API_URL}/api/v1/settings`, {
next: { revalidate: 300 } // 5 dk cache
});
return res.json();
}
export default async function RootLayout({ children }) {
const settings = await getSettings();
return (
{/* Analytics Scripts */}
{settings.analytics?.google_tag_manager_id && (
)}
{settings.analytics?.custom_head_scripts && (
)}
{children}
{settings.analytics?.custom_body_scripts && (
)}
);
}
```
### 2. Boolean Değerler
Backend tüm değerleri **string** olarak döner. Boolean kontrol:
```tsx
// Helper fonksiyon
const isEnabled = (value: string | null) => value === "true";
// Kullanım
{isEnabled(settings.general.announcement_bar_active) && (
)}
{isEnabled(settings.header.show_phone_topbar) && (
{settings.contact.phone_primary}
)}
```
### 3. Image Alanları
Image değerleri relative path olarak gelir. API base URL ile birleştir:
```tsx
const getImageUrl = (path: string | null) => {
if (!path) return null;
if (path.startsWith('http')) return path;
return `${process.env.NEXT_PUBLIC_API_URL}${path}`;
};
// Kullanım
```
---
## Bileşen Bazlı Kullanım Haritası
### Header / Navbar
| Ayar | Kullanım |
|------|----------|
| `general.logo_light` | Navbar logo (transparent bg) |
| `general.logo_dark` | Navbar logo (scrolled/white bg) |
| `general.announcement_bar_*` | Üst duyuru barı |
| `header.navbar_style_default` | Navbar başlangıç stili |
| `header.cta_button_text/url/color` | Sağ üst CTA butonu |
| `header.show_*_topbar` | Topbar'da göster/gizle kontrolleri |
| `header.show_social_navbar` | Sosyal medya ikonları |
| `contact.phone_primary` | Topbar telefon |
| `contact.email_info` | Topbar e-posta |
| `contact.address_short` | Topbar adres |
| `contact.working_hours_weekday` | Topbar çalışma saatleri |
| `social.*_url` | Sosyal medya ikon linkleri |
### Footer
| Ayar | Kullanım |
|------|----------|
| `footer.footer_logo` | Footer logo |
| `footer.footer_description` | Footer açıklama metni |
| `footer.footer_address` | Adres |
| `footer.footer_phone` | Telefon |
| `footer.footer_email` | E-posta |
| `footer.copyright_text` | Copyright satırı |
| `footer.footer_bg_color` | Background rengi |
| `footer.show_social_footer` | Sosyal medya göster/gizle |
| `social.*_url` | Sosyal medya ikon linkleri |
### SEO / Head Meta Tags
```tsx
// Her sayfa için generateMetadata
export async function generateMetadata(): Promise {
const settings = await getSettings();
const seo = settings.seo;
return {
title: {
template: `%s ${seo.meta_title_separator} ${seo.og_site_name}`,
default: settings.general.site_name,
},
description: seo.default_meta_description,
keywords: seo.default_meta_keywords,
robots: seo.robots,
openGraph: {
type: seo.og_type,
locale: seo.og_locale,
siteName: seo.og_site_name,
images: seo.og_image ? [getImageUrl(seo.og_image)] : [],
},
twitter: {
card: seo.twitter_card_type,
site: seo.twitter_site,
creator: seo.twitter_creator,
},
verification: {
google: seo.google_site_verification,
other: {
'yandex-verification': seo.yandex_verification,
'msvalidate.01': seo.bing_site_verification,
},
},
};
}
```
### İletişim Sayfası
| Ayar | Kullanım |
|------|----------|
| `contact.phone_primary/secondary` | Telefon numaraları |
| `contact.email_*` | E-posta adresleri |
| `contact.address_full` | Tam adres |
| `contact.working_hours_*` | Çalışma saatleri |
| `contact.whatsapp_number/message` | WhatsApp butonu |
| `maps.google_maps_embed_url` | Harita iframe |
| `maps.google_maps_place_url` | "Google Maps'te Aç" linki |
| `maps.latitude/longitude` | Marker konumu |
### WhatsApp Floating Button
```tsx
const whatsappUrl = settings.contact.whatsapp_number
? `https://wa.me/${settings.contact.whatsapp_number.replace(/\s/g, '')}?text=${encodeURIComponent(settings.contact.whatsapp_message || '')}`
: null;
{whatsappUrl && WhatsApp}
```
### Bakım Modu
```tsx
// middleware.ts veya layout.tsx
if (isEnabled(settings.general.maintenance_mode)) {
return ;
}
```
---
## Cache Stratejisi
| Strateji | Açıklama |
|----------|----------|
| Backend | 1 saat cache (`Cache::remember`, 3600s) |
| Frontend (ISR) | `next: { revalidate: 300 }` — 5 dakika |
| Admin güncelleme sonrası | Backend cache otomatik temizlenir, frontend 5 dk içinde güncellenir |
| Acil güncelleme | Admin panelden "Cache Temizle" → frontend revalidate |
---
## Null Değer Kontrolü
Birçok ayar başlangıçta `null` olabilir. Her kullanımda null check yap:
```tsx
// Kötü
Instagram
// İyi
{settings.social?.instagram_url && (
Instagram
)}
```
Sosyal medya ikonlarını dinamik render et — sadece URL'si dolu olanları göster:
```tsx
const socialLinks = [
{ key: 'instagram_url', icon: Instagram, label: 'Instagram' },
{ key: 'facebook_url', icon: Facebook, label: 'Facebook' },
{ key: 'twitter_url', icon: Twitter, label: 'X' },
{ key: 'youtube_url', icon: Youtube, label: 'YouTube' },
{ key: 'linkedin_url', icon: Linkedin, label: 'LinkedIn' },
{ key: 'tiktok_url', icon: TikTok, label: 'TikTok' },
];
{socialLinks
.filter(s => settings.social?.[s.key])
.map(s => (
))
}
```
---
## TypeScript Tipi (Önerilen)
```ts
interface SiteSettings {
general: Record;
contact: Record;
maps: Record;
social: Record;
seo: Record;
analytics: Record;
header: Record;
footer: Record;
}
```