Proje: Okul Platform · Hub: Okul Platform — Conventions

Responsive modülde Alpine component’lere karmaşık prop’lar geçirirken iki sürekli-tekrarlanan tuzak: (a) HTML attribute tırnak escape hell, (b) bundle yüklenme sırasında Alpine.start() alpine:init’ten önce ateşleme.

(a) x-data’ya payload geçirirken @js() kullan

Yanlış — tırnak karmaşası, SyntaxError: expected expression, got '}', zincirleme ... is not defined hataları:

<div x-data='myComponent({
    comments:  {!! $commentPayloadJson !!},
    articleId: {{ (int) $article->id }},
    storeUrl:  @js(route("ajax.x.store")),
    initialName: @js(auth()->user()->name),
    isLoggedIn: {{ auth()->check() ? "true" : "false" }}
})'>

@js() outer string’in içinde JSON.parse('...') üretir, dış single-quote attribute’u kırar; apostrofu olan user->name veya nested JSON bozabilir.

Doğru — tek PHP array + tek @js():

@php
    $componentProps = [
        'comments'     => $commentPayload,
        'articleId'    => (int) ($article->id ?? 0),
        'storeUrl'     => route('ajax.x.store'),
        'initialName'  => auth()->check() ? auth()->user()->name  : '',
        'isLoggedIn'   => auth()->check(),
    ];
@endphp
<div x-data="myComponent(@js($componentProps))">

@js($array) tek bir JSON.parse('{...escaped...}') expression üretir; HTML attribute’ta güvenli, string-içinde-tırnak kaçmaz.

(b) alpine-core + page script load-order

Alpine.js layout’ta bundle’lanırken (resources/assets/scripts/responsive/alpine-core.js), Alpine.start()’ı DOMContentLoaded’a kadar geciktir. Defer script’ler document order’da çalışır; core sayfa script’inden ÖNCE yüklenir. Eğer Alpine.start() hemen çağrılırsa page-level script (article-page.js, article-list.js) alpine:init listener’ını eklemeden event fire olur, component’ler asla register olmaz ve kullanıcı HTML’de beklenen alanların tamamı ReferenceError: X is not defined hatası verir.

// alpine-core.js — layout-seviyesi bundle
import Alpine from 'alpinejs';
window.Alpine = Alpine;
 
const start = () => {
    if (window.__alpineStarted) return;
    window.__alpineStarted = true;
    Alpine.start();
};
 
// DOMContentLoaded tüm defer script'lerin sonunda fire olur, bu pencereye
// kadar page-level `document.addEventListener('alpine:init', ...)` kayıt
// edilmiş olacak.
if (document.readyState === 'complete') {
    Promise.resolve().then(start);
} else {
    document.addEventListener('DOMContentLoaded', start, { once: true });
}

Page bundle:

document.addEventListener('alpine:init', () => {
    const Alpine = window.Alpine;
    if (!Alpine) return;
    Alpine.data('myComponent', () => ({ ... }));
});

Semptom → sebep hızlı eşleşme

SemptomMuhtemel sebep
Uncaught SyntaxError: expected expression, got '}' + zincirleme X is not definedx-data attribute quote escape (kural a)
Component sessiz kalıyor, tüm x-show / x-text kırılıyorAlpine hiç register olmadı (kural b — core hemen start ediyor)
Sadece ilk sayfa yüklemesinde sorunsuz, AJAX partial sonrası deadlinkAlpine yeni DOM’u otomatik tarar; partial’da yeni x-data varsa page script’i de alpine:init sonrası yeniden register yapmalı