Konu

Hızlı Başlangıç — İlk OG Görselinizi Oluşturun

Bu FastOG hızlı başlangıç kılavuzu, ilk dinamik Open Graph görselinizi dakikalar içinde yayına almanızı sağlar. Kayıt olmak ücretsizdir — ardından işleme kotası için bir Dynamic API planı seçin. API anahtarınızı ve HMAC gizli anahtarınızı panelde ihtiyacınız olduğunda oluşturabilirsiniz. Her işleme temizdir — hiçbir planda filigran yoktur, ücretsiz test aracı dahildir. Boru hattını çalışırken görmek için Ücretsiz OG Görsel Test Aracı'nı deneyin, ardından aşağıdaki adımlarla kendi URL'lerinizi imzalayın.

Nasıl çalışır — Mimari

FastOG, talep üzerine OG görselleri (on-demand OG images) için tasarlanmıştır: web siteniz, sayfa oluşturma anında bir URL'yi imzalar, tarayıcı (crawler) bunu getirir, FastOG PNG'yi bir kez oluşturur ve Cloudflare bunu önbelleğe alır; böylece sonraki her getirme işlemi anlık ve ücretsizdir.

sequenceDiagram
    participant You as You share a link
    participant Crawler as Social crawler
    participant Site as Your website
    participant FastOG as FastOG API
    participant Edge as Edge cache

    You->>Crawler: share a link to your post
    Crawler->>Site: GET the page without JavaScript
    Site->>Site: sign the og:image URL at render time
    Site-->>Crawler: HTML with signed og:image URL
    Crawler->>Edge: fetch the og:image URL
    Edge->>FastOG: cache miss, first time
    FastOG->>FastOG: verify the HMAC covers the exact params
    FastOG-->>Edge: render PNG, counts 1 toward monthly quota, cached for 1 year
    Edge-->>Crawler: PNG
    Crawler-->>You: image shown in the post preview
    Note over Edge, Crawler: identical params and URL mean a cache hit with no render

Onu "sorunsuz çalıştıran" üç kural

  1. İçeriği imzalayın, saati değil. İmza, her parametreyi (başlık, şablon, …) kapsar. Aynı parametreler her zaman aynı URL'yi üretir — uç önbelleği (edge cache) bu sayede çalışır: aynı içerik → aynı URL → sonsuz önbellek isabeti.
  2. Görsel, ilk oluşturmadan sonra kalıcıdır. İmza yalnızca ilk oluşturmayı korur. Bir görsel oluşturulduktan sonra FastOG'un uç sunucusu, onu içerik parametrelerine göre bir yıl boyunca saklar; aynı parametrelerle yapılan sonraki istekler uç sunucudan sunulur ve oluşturucuya asla ulaşmaz (kotanızdan düşülmez). Önbelleğe alınmış içerikteki geçersiz bir imza, yine de önbelleğe alınmış PNG'yi döndürür (yanıt hangi katmanın yanıt verdiğini bildirir: X-FastOG-Worker-Cache: HIT veya R2); yalnızca bir önbellek isabetsizliği 401 alır.
  3. Tek hata modu. Değiştirilmiş bir URL (birinin title/template değerlerini değiştirmesi), önbellek isabetsizliğinde FastOG'da 401 alır — bu nedenle kotanızı harcamak için asla kullanılamaz. Meşru URL'ler asla süresi dolmaz: anahtarın HMAC gizli anahtarını döndürene kadar geçerli kalırlar.

1. API Anahtarınızı ve HMAC Sırrınızı Alın

  1. FastOG Panosu → API Anahtarları bölümüne gidin

  2. "Yeni API Anahtarı Oluştur" seçeneğine tıklayın

  3. Bir ad verin (ör. "Üretim Web Sitesi")

  4. Her iki değeri de kopyalayın (yalnızca bir kez gösterilir!):

    • API Anahtarı: sk_... (ön ekten sonra 32 karakter)
    • HMAC Sırrı: 64 karakterlik onaltılık dize
  5. Bunları ortam değişkenlerinize kaydedin:

env
# Your website backend .env
FASTOG_API_KEY=sk_your_full_api_key
FASTOG_HMAC_SECRET=a1b2c3d4e5f6...  # 64 chars
FASTOG_API_URL=https://fastog.com/api/v1/og

2. URL İmzalama Fonksiyonunu Uygulama

Birden fazla framework ve desen içeren eksiksiz eğitimler için bkz.:

Node.js / Next.js

javascript
// lib/fastog-signer.js
import crypto from "crypto";

// RFC-3986 encode (encodeURIComponent leaves !'()* unencoded).
const enc = (s) =>
    encodeURIComponent(s).replace(
        /[!'()*]/g,
        (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase(),
    );

export function generateOgImageUrl(params) {
    const baseUrl = process.env.FASTOG_API_URL;
    const apiKey = process.env.FASTOG_API_KEY;
    const hmacSecret = process.env.FASTOG_HMAC_SECRET;

    const all = { ...params, key: apiKey };

    // Canonical: every param (except s), sorted, RFC-3986 encoded, joined with "&".
    const pairs = [];
    for (const [k, v] of Object.entries(all)) {
        for (const vv of Array.isArray(v) ? v : [v])
            pairs.push(`${enc(k)}=${enc(vv)}`);
    }
    pairs.sort();
    const canonical = pairs.join("&");

    // Content-signed: message = path + canonical query. No timestamp.
    const signature = crypto
        .createHmac("sha256", hmacSecret)
        .update(`GET/api/v1/og\n${canonical}`)
        .digest("hex");

    const url = new URL(baseUrl);
    for (const [k, v] of Object.entries(all)) {
        for (const vv of Array.isArray(v) ? v : [v])
            url.searchParams.append(k, vv);
    }
    url.searchParams.set("s", signature);
    return url.toString();
}

PHP (Laravel)

php
// app/Services/QuickogSigner.php
function generateOgImageUrl(array $params): string
{
    $baseUrl = config('services.fastog.api_url', 'https://fastog.com/api/v1/og');
    $apiKey = config('services.fastog.api_key');
    $hmacSecret = config('services.fastog.hmac_secret');

    $all = array_merge($params, ['key' => $apiKey]);

    // Canonical: every param except s, keys sorted (array values sorted too),
    // RFC-3986 encoded, joined with '&'. Content-signed — no timestamp.
    $pairs = [];
    foreach ($all as $k => $v) {
        $values = is_array($v) ? $v : [$v];
        sort($values, SORT_STRING);
        foreach ($values as $vv) {
            $pairs[] = rawurlencode((string) $k) . '=' . rawurlencode((string) $vv);
        }
    }
    sort($pairs, SORT_STRING);
    $canonical = implode('&', $pairs);

    $signature = hash_hmac('sha256', 'GET/api/v1/og' . "\n" . $canonical, $hmacSecret);

    return $baseUrl . '?' . http_build_query(array_merge($all, ['s' => $signature]));
}

Python (Django/FastAPI)

python
# utils/fastog.py
import hmac
import hashlib
import os
from urllib.parse import quote, urlencode

def _enc(s):
    return quote(str(s), safe='-._~')  # RFC-3986: only unreserved chars

def generate_og_image_url(params: dict) -> str:
    base_url = os.environ['FASTOG_API_URL']
    api_key = os.environ['FASTOG_API_KEY']
    hmac_secret = os.environ['FASTOG_HMAC_SECRET']

    all_params = {**params, 'key': api_key}

    # Canonical: every param except s, sorted, RFC-3986 encoded, joined with '&'.
    pairs = []
    for k, v in all_params.items():
        for vv in sorted(v if isinstance(v, list) else [v]):
            pairs.append(f"{_enc(k)}={_enc(vv)}")
    canonical = '&'.join(sorted(pairs))

    # Content-signed: message = path + canonical query. No timestamp.
    signature = hmac.new(
        hmac_secret.encode(),
        f"GET/api/v1/og\n{canonical}".encode(),
        hashlib.sha256,
    ).hexdigest()

    return f"{base_url}?{urlencode({**all_params, 's': signature})}"

3. Blogunuzda/Web Sitenizde Kullanım

Next.js App Router

tsx
// app/blog/[slug]/page.tsx
import { generateOgImageUrl } from "@/lib/fastog-signer";

export async function generateMetadata({ params }) {
    const post = await getPost(params.slug);

    const ogImageUrl = generateOgImageUrl({
        template: "blog",
        title: post.title,
        subtitle: post.excerpt,
        author: post.author.name,
    });

    return {
        title: post.title,
        description: post.excerpt,
        openGraph: {
            images: [ogImageUrl],
        },
    };
}

Laravel Blade

blade
{{-- resources/views/blog/show.blade.php --}}
@php
    $ogImageUrl = generateOgImageUrl([
        'template' => 'blog',
        'title' => $post->title,
        'subtitle' => $post->excerpt,
        'author' => $post->author->name,
    ]);
@endphp

<head>
    <meta property="og:image" content="{{ $ogImageUrl }}" />
    <meta property="og:title" content="{{ $post->title }}" />
    <meta property="og:description" content="{{ $post->excerpt }}" />
</head>

Django Template

django
{# blog/post_detail.html #}
{% load fastog_tags %}

<head>
    <meta property="og:image" content="{% generate_og_image_url post %}" />
    <meta property="og:title" content="{{ post.title }}" />
    <meta property="og:description" content="{{ post.excerpt }}" />
</head>

4. Uygulamanızı Test Edin

bash
# Generate a test URL
node -e "
const { generateOgImageUrl } = require('./lib/fastog-signer');
console.log(generateOgImageUrl({ title: 'Test', template: 'default' }));
"

# Test with curl
curl "https://fastog.com/api/v1/og?title=Test&key=sk_quick_123abc&s=<sig>"

Beklenen:

  • ✅ Geçerli imza → OG görselini döndürür
  • ❌ Değiştirilmiş parametre (ör. title değiştirildi) → {"code": "invalid_signature"}
  • ❌ Geçersiz imza → {"code": "invalid_signature"}

5. Güvenlik Kontrol Listesi

  • [ ] HMAC gizli anahtarı ortam değişkenlerinde saklanıyor (kod içinde değil)
  • [ ] Tüm istekler için HTTPS kullanılıyor
  • [ ] Gizli anahtar istemci tarafı JavaScript'te asla açığa çıkarılmıyor
  • [ ] Başarısız imza denemeleri izleniyor

6. Hataları Ele Alma

javascript
if (response.status === 401) {
    const error = await response.json();

    switch (error.code) {
        case "missing_signature":
            // URL is missing `key` or `s` — re-generate it with your signer.
            break;
        case "invalid_signature":
            // A param changed after signing, or the secret doesn't match.
            // Re-sign the URL after any content change; verify the secret on both sides.
            break;
    }
}

Sonraki Adımlar

  1. Web sitenizin arka ucunda imzalama işlemini uygulayın (eğiticilere bakın)
  2. FastOG API ile test edin
  3. Başarısız imza denemeleri için günlükleri izleyin
  4. Tekrarlanan hatalar için uyarı sistemi kurun

Tam dokümantasyon için HMAC İmza Kılavuzu bölümüne bakın.

Tam API Referansı

Ücretsiz deneyin — kayıt gerekmez

Dinamik OG görsellerini saniyeler içinde önizleyin ve test edin.

Ücretsiz OG Görsel Test Aracını Aç

A BeCaSimulations site