← Kursa Dön
📄 Text · 30 min

GitHub Pages

Giriş — Ücretsiz Barınma Hakkı

Bir yazılımcının portföy sitesi olmalı mı? Kesinlikle evet. Peki bir web sitesi barındırmak (hosting) için para mı vermek gerekir? Artık hayır. GitHub Pages, her GitHub kullanıcısına ücretsiz statik web sitesi barındırma imkânı sunar. Üstelik kendi domain adınızı da bağlayabilirsiniz.

Bunu bir emlakçıya gitmeye benzetebilirsiniz: "Size bedava bir arsa veriyoruz. Üzerine istediğiniz evi yapın. Adres de vereceğiz." İşte GitHub Pages tam olarak bu teklifi yapıyor.

Blog yazmak, portföy oluşturmak, proje dökümantasyonu yayınlamak, hatta basit web uygulamalarını host etmek — bunların hepsi GitHub Pages ile mümkün.

GitHub Pages Nedir?

GitHub Pages, bir GitHub repository'sindeki statik dosyaları (HTML, CSS, JavaScript) web sitesi olarak yayınlayan bir servistir.

Repository dosyaları                    Web sitesi
┌──────────────────┐                ┌──────────────────┐
│ index.html       │                │                  │
│ style.css        │  ──────────►   │  kullanici.      │
│ script.js        │   GitHub       │  github.io       │
│ images/          │   Pages        │                  │
│ about.html       │                │                  │
└──────────────────┘                └──────────────────┘

Temel Özellikler

✅ Ücretsiz hosting
✅ HTTPS otomatik (SSL sertifikası dahil)
✅ Custom domain desteği
✅ Jekyll entegrasyonu (statik site generator)
✅ GitHub Actions ile otomatik deploy
✅ 1 GB depolama limiti
✅ Aylık 100 GB bandwidth
✅ Soft limit: site boyutu < 1 GB

İlk GitHub Pages Sitesi

Yöntem 1: Kullanıcı/Organization Sitesi

Her GitHub kullanıcısı username.github.io adresinde bir site yayınlayabilir:

# 1. Özel isimli repo oluştur
# Repo adı MUTLAKA username.github.io olmalı
gh repo create yourusername.github.io --public

# 2. Klonla
git clone https://github.com/yourusername/yourusername.github.io.git
cd yourusername.github.io

# 3. index.html oluştur
cat > index.html << 'EOF'
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Merhaba Dünya!</title>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 2rem;
            background: #0d1117;
            color: #e6edf3;
        }
        h1 { color: #58a6ff; }
        a { color: #58a6ff; }
    </style>
</head>
<body>
    <h1>👋 Merhaba, ben [İsminiz]!</h1>
    <p>Full-stack developer. JavaScript, React, Node.js.</p>
    <ul>
        <li><a href="https://github.com/yourusername">GitHub</a></li>
        <li><a href="mailto:you@email.com">Email</a></li>
    </ul>
</body>
</html>
EOF

# 4. Push et
git add index.html
git commit -m "feat: create personal site"
git push origin main

# 5. Birkaç dakika bekleyin...
# https://yourusername.github.io adresinde siteniz yayında! 🎉

Yöntem 2: Proje Sitesi

Her repo'nun kendi Pages sitesi olabilir:

# Repository: yourusername/my-project
# Site adresi: yourusername.github.io/my-project

# Ayar:
# Settings → Pages → Source
#   Branch: main (veya gh-pages)
#   Folder: / (root) veya /docs
URL yapısı:
─────────────────────────────────────────────────
Kullanıcı sitesi:  username.github.io
Proje sitesi:      username.github.io/repo-name
Org sitesi:        orgname.github.io
Org proje sitesi:  orgname.github.io/repo-name

Jekyll — Statik Site Generator

Jekyll Nedir?

GitHub Pages, yerleşik olarak Jekyll destekler. Jekyll, Markdown dosyalarınızı otomatik olarak güzel HTML sayfalarına dönüştürür. Blog yazarken HTML yazmak yerine Markdown yazarsınız — Jekyll gerisini halleder.

Siz yazarsınız:              Jekyll üretir:
┌────────────────┐          ┌──────────────────┐
│ # Başlık       │          │ <h1>Başlık</h1>  │
│                │          │                  │
│ Bu bir blog    │  ────►   │ <p>Bu bir blog   │
│ yazısıdır.     │          │ yazısıdır.</p>   │
│                │          │ + tema + nav +   │
│ - madde 1      │          │ footer + CSS     │
│ - madde 2      │          │                  │
└────────────────┘          └──────────────────┘

Jekyll Proje Yapısı

my-blog/
├── _config.yml          # Site konfigürasyonu
├── _posts/              # Blog yazıları
│   ├── 2024-01-15-ilk-yazi.md
│   └── 2024-02-20-git-ogrenmek.md
├── _layouts/            # Sayfa şablonları
│   ├── default.html
│   └── post.html
├── _includes/           # Tekrar kullanılabilir parçalar
│   ├── header.html
│   └── footer.html
├── assets/              # CSS, JS, resimler
│   ├── css/
│   └── images/
├── index.md             # Ana sayfa
├── about.md             # Hakkımda
└── Gemfile              # Ruby dependencies

_config.yml

# _config.yml
title: "Ahmet'in Blog'u"
description: "Yazılım geliştirme üzerine düşünceler"
url: "https://ahmet.github.io"
baseurl: ""

# Tema
theme: minima        # GitHub Pages'te yerleşik temalar
# remote_theme: pages-themes/cayman@v0.2.0  # Custom tema

# Yazar bilgisi
author:
  name: Ahmet Yılmaz
  email: ahmet@email.com

# Blog ayarları
permalink: /:year/:month/:title/
paginate: 10

# Markdown engine
markdown: kramdown
highlighter: rouge

# Sosyal medya
github_username: ahmet
twitter_username: ahmet_dev

Blog Yazısı Oluşturma

---
layout: post
title: "Git ile Versiyon Kontrolüne Giriş"
date: 2024-01-15 10:00:00 +0300
categories: [git, tutorial]
tags: [git, version-control, beginners]
author: Ahmet Yılmaz
excerpt: "Git nedir, neden kullanmalıyız ve nasıl başlarız?"
---

# Git ile Versiyon Kontrolüne Giriş

Versiyon kontrolü, yazılım geliştirmenin temel taşlarından biridir.
Bu yazıda Git'in temellerini öğreneceğiz.

## Git Nedir?

Git, dağıtık bir versiyon kontrol sistemidir...

```bash
git init
git add .
git commit -m "initial commit"

Neden Git?

  • Takım çalışması

  • Geçmiş takibi

  • Branch desteği

![Git Logo](/assets/images/git-logo.png)


> 💡 **İpucu:** Blog yazıları `_posts` klasöründe olmalı ve dosya adı `YYYY-MM-DD-baslik.md` formatında olmalıdır. Bu format zorunludur, aksi halde Jekyll dosyayı tanımaz.

### Jekyll Temaları

GitHub Pages'te yerleşik olarak desteklenen temalar:

```yaml
# _config.yml'de kullanılabilecek temalar
theme: minima          # Varsayılan, minimal blog teması
theme: jekyll-theme-cayman
theme: jekyll-theme-slate
theme: jekyll-theme-minimal
theme: jekyll-theme-hacker
theme: jekyll-theme-architect
theme: jekyll-theme-tactile
theme: jekyll-theme-midnight
theme: jekyll-theme-dinky
theme: jekyll-theme-time-machine
theme: jekyll-theme-leap-day
theme: jekyll-theme-merlot

Harici tema kullanmak için:

# remote_theme kullanın
remote_theme: just-the-docs/just-the-docs
# veya
remote_theme: pmarsceill/just-the-docs@v0.4.0

Modern Alternatif: Jekyll Yerine Static Site Generators

Jekyll güzel ama eski sayılır. Modern alternatifler daha hızlı ve esnek:

Framework    │ Dil        │ Özellik
─────────────┼────────────┼──────────────────────
Jekyll       │ Ruby       │ GitHub Pages native
Hugo         │ Go         │ En hızlı build
Next.js      │ React      │ SSG + SSR + API routes
Gatsby       │ React      │ GraphQL, plugin ekosistemi
Astro        │ Multi      │ Minimum JS, island arch
Docusaurus   │ React      │ Dökümantasyon odaklı
VitePress    │ Vue        │ Vue ekosistemi doklar
11ty         │ JS         │ Basit, esnek, hızlı

Bu framework'lerin hepsi GitHub Pages ile kullanılabilir — GitHub Actions ile build edip deploy edersiniz.

Custom Domain Bağlama

Adım 1: Domain Satın Alma

Bir domain kayıt firmasından (Namecheap, Cloudflare, Google Domains, vs.) domain satın alın.

Adım 2: DNS Ayarları

DNS Kayıtları (Domain sağlayıcınızda):

# A kayıtları (apex domain: example.com)
A    @    185.199.108.153
A    @    185.199.109.153
A    @    185.199.110.153
A    @    185.199.111.153

# CNAME kaydı (www subdomain)
CNAME   www   yourusername.github.io.

Adım 3: GitHub Ayarları

# Repo'nun root'una CNAME dosyası ekleyin
echo "www.example.com" > CNAME
git add CNAME
git commit -m "chore: add custom domain"
git push

# veya GitHub UI'dan:
# Settings → Pages → Custom domain → "www.example.com" → Save

Adım 4: HTTPS Aktifleştirme

Settings → Pages → Custom domain
  ☑ Enforce HTTPS

DNS check:
  ✅ DNS check successful
  ✅ HTTPS certificate provisioned
DNS Propagation süresi: 24-48 saat olabilir
Certificate provisioning: 15-30 dakika

Kontrol etmek için:
$ dig www.example.com +short
yourusername.github.io.
185.199.108.153

⚠️ Dikkat: CNAME dosyasını repository'ye eklemeyi unutmayın! Bu dosya olmadan GitHub custom domain ayarınızı her deploy'da kaybeder. Actions ile deploy ediyorsanız, build çıktısına CNAME dosyasını dahil edin.

GitHub Actions ile Deploy

Modern projelerde (React, Next.js, Vue, Hugo vb.) build adımı gereklidir. GitHub Actions ile otomatik build ve deploy:

React/Vite Projesi Deploy

# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

# GITHUB_TOKEN izinleri
permissions:
  contents: read
  pages: write
  id-token: write

# Eşzamanlı deploy'ları engelle
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build
        env:
          BASE_URL: /${{ github.event.repository.name }}/

      - name: Setup Pages
        uses: actions/configure-pages@v4

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: './dist'  # Vite build çıktısı

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Next.js Static Export Deploy

# .github/workflows/deploy.yml
name: Deploy Next.js to GitHub Pages

on:
  push:
    branches: [main]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build
        env:
          NEXT_PUBLIC_BASE_PATH: /${{ github.event.repository.name }}

      - uses: actions/upload-pages-artifact@v3
        with:
          path: './out'  # next export çıktısı

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - uses: actions/deploy-pages@v4
        id: deployment
// next.config.js (Static export için)
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  basePath: process.env.NEXT_PUBLIC_BASE_PATH || '',
  images: {
    unoptimized: true,  // Static export'ta image optimization yok
  },
};

module.exports = nextConfig;

Hugo Deploy

# .github/workflows/deploy.yml
name: Deploy Hugo to GitHub Pages

on:
  push:
    branches: [main]

permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive  # Hugo temaları genelde submodule

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v3
        with:
          hugo-version: 'latest'
          extended: true

      - name: Build
        run: hugo --minify

      - uses: actions/upload-pages-artifact@v3
        with:
          path: './public'

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - uses: actions/deploy-pages@v4
        id: deployment

Pages Kaynağını Actions Olarak Ayarlama

Settings → Pages → Build and deployment
  Source: GitHub Actions  (← bunu seçin)

Portfolyo Sitesi Yapma

GitHub Pages'in en yaygın kullanımı portföy sitesidir. İşte basit ama etkili bir portföy yapısı:

<!-- index.html — Modern, minimal portföy -->
<!DOCTYPE html>
<html lang="tr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ahmet Yılmaz — Full-Stack Developer</title>
    <style>
        :root {
            --bg: #0d1117;
            --text: #e6edf3;
            --accent: #58a6ff;
            --card: #161b22;
            --border: #30363d;
        }
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: system-ui, sans-serif;
            background: var(--bg);
            color: var(--text);
            line-height: 1.6;
        }
        .container { max-width: 900px; margin: 0 auto; padding: 2rem; }
        h1 { font-size: 2.5rem; margin-bottom: 0.5rem; }
        .subtitle { color: #8b949e; font-size: 1.2rem; }
        .projects { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; margin-top: 2rem; }
        .card {
            background: var(--card);
            border: 1px solid var(--border);
            border-radius: 8px;
            padding: 1.5rem;
        }
        .card h3 { color: var(--accent); }
        .tag { display: inline-block; background: #1f2937; padding: 2px 8px; border-radius: 4px; font-size: 0.85rem; margin: 2px; }
        a { color: var(--accent); text-decoration: none; }
        a:hover { text-decoration: underline; }
    </style>
</head>
<body>
    <div class="container">
        <header style="margin: 3rem 0;">
            <h1>👋 Merhaba, ben Ahmet</h1>
            <p class="subtitle">Full-Stack Developer | React, Node.js, TypeScript</p>
            <p style="margin-top: 1rem;">
                <a href="https://github.com/ahmet">GitHub</a> ·
                <a href="https://linkedin.com/in/ahmet">LinkedIn</a> ·
                <a href="mailto:ahmet@email.com">Email</a>
            </p>
        </header>

        <section>
            <h2>🚀 Projeler</h2>
            <div class="projects">
                <div class="card">
                    <h3>TaskFlow</h3>
                    <p>Kanban tarzı proje yönetim uygulaması.</p>
                    <div style="margin-top: 0.5rem;">
                        <span class="tag">React</span>
                        <span class="tag">TypeScript</span>
                        <span class="tag">Firebase</span>
                    </div>
                    <p style="margin-top: 0.5rem;">
                        <a href="#">Demo</a> · <a href="#">Kaynak Kod</a>
                    </p>
                </div>
                <div class="card">
                    <h3>WeatherNow</h3>
                    <p>Anlık hava durumu API entegrasyonu.</p>
                    <div style="margin-top: 0.5rem;">
                        <span class="tag">Vue.js</span>
                        <span class="tag">OpenWeather API</span>
                    </div>
                    <p style="margin-top: 0.5rem;">
                        <a href="#">Demo</a> · <a href="#">Kaynak Kod</a>
                    </p>
                </div>
            </div>
        </section>
    </div>
</body>
</html>

💡 İpucu: Portfolio sitenizde sadece proje listelemeyin. Her projenin neyi çözdüğünü, hangi teknolojileri neden seçtiğinizi ve öğrendiğiniz dersleri kısaca yazın. Recruiter'lar koda bakmaz, hikayeye bakar.

SPA (Single Page App) Routing Sorunu

React Router veya Vue Router gibi client-side routing kullanan uygulamalarda, kullanıcı /about gibi bir path'e doğrudan gittiğinde GitHub Pages 404 döner. Çünkü sunucu tarafında /about.html diye bir dosya yoktur.

Çözüm: 404.html Redirect Trick

<!-- 404.html — tüm route'ları index.html'e yönlendir -->
<!DOCTYPE html>
<html>
<head>
    <script>
        // Path'i query string'e çevir ve index.html'e yönlendir
        const path = window.location.pathname;
        const search = window.location.search;
        const hash = window.location.hash;
        window.location.replace(
            window.location.origin +
            '/?p=' + encodeURIComponent(path + search + hash)
        );
    </script>
</head>
</html>
<!-- index.html'de (body'nin başına) -->
<script>
    // 404.html'den yönlendirilen path'i geri al
    (function() {
        const params = new URLSearchParams(window.location.search);
        const path = params.get('p');
        if (path) {
            window.history.replaceState(null, '', path);
        }
    })();
</script>

Yaygın Hatalar

1. Base Path Unutmak

# Proje sitesi: username.github.io/my-project
# Tüm asset path'leri /my-project/ prefix'i ile olmalı

# ❌ Yanlış
<link rel="stylesheet" href="/style.css">
<img src="/logo.png">

# ✅ Doğru — relative path
<link rel="stylesheet" href="style.css">
<img src="logo.png">

# ✅ Doğru — base path ile
<link rel="stylesheet" href="/my-project/style.css">

2. Build Çıktısını Push Etmemek

# ❌ Kaynak kodu push ettiniz ama build çıktısı yok
# GitHub Pages ham React/Vue kodu render edemez!

# ✅ GitHub Actions ile build + deploy
# veya gh-pages branch'ine build çıktısını push

3. CNAME Kaybı

# ❌ Her deploy'da custom domain kayboluyor
# Çünkü CNAME dosyası build çıktısında yok

# ✅ CNAME dosyasını public/ (veya static/) klasörüne koyun
# Build sonrası dist/'e kopyalanır
echo "www.mysite.com" > public/CNAME

Özet

Bu derste GitHub Pages ile web sitesi yayınlamanın tüm yönlerini öğrendik:

  • 🌐 GitHub Pages — her repo'dan ücretsiz statik web sitesi

  • 📝 Jekyll — Markdown'dan blog/site oluşturma, yerleşik destek

  • 🎨 Modern framework'ler — React, Next.js, Hugo + Actions deploy

  • 🔗 Custom domain — kendi domain adınızı bağlama, HTTPS otomatik

  • 🚀 GitHub Actions deploy — build + deploy otomasyonu

  • 💼 Portfolyo — kişisel site ile kendinizi tanıtma

  • ⚙️ SPA routing — 404.html trick ile client-side routing

Bir sonraki derste GitHub Packages'ı keşfedeceğiz: npm paketleri yayınlama, container registry ve paket yönetimi.