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
| Semptom | Muhtemel sebep |
|---|---|
Uncaught SyntaxError: expected expression, got '}' + zincirleme X is not defined | x-data attribute quote escape (kural a) |
Component sessiz kalıyor, tüm x-show / x-text kırılıyor | Alpine hiç register olmadı (kural b — core hemen start ediyor) |
| Sadece ilk sayfa yüklemesinde sorunsuz, AJAX partial sonrası deadlink | Alpine yeni DOM’u otomatik tarar; partial’da yeni x-data varsa page script’i de alpine:init sonrası yeniden register yapmalı |
Related
- 2026-04-15-responsive-component-contract — Blade component state/method sözleşmesi
- 2026-04-16-responsive-ajax-partial-pattern — partial response + Alpine replace/append
- 2026-04-16-inline-script-extraction-guidelines — JS bundle stratejisi