Guides
Common problems, why they happen, and how to fix them.
Symptom: interactive widgets (Modal, Dropdown, Tabs, Toast, …) render fine in the HTML but clicking them does nothing. Your browser's network tab shows assets/runtime/serixa.js returning 404.
Cause: ClientRuntime::register($assets, $url) only writes a <script defer src="$url"> tag. It does not guarantee that file exists at that URL — serving it is your app's job.
Fix:
public/, not the app root: php -S localhost:8000 -t public. If you serve from the app root, /assets/runtime/serixa.js resolves to a path that doesn't exist.serixa new copies it to public/assets/runtime/serixa.js automatically. If you deleted it, copy it back from Serixa\Runtime\ClientRuntime::scriptPath().register() matches where the file lives: ``php ClientRuntime::register($document->assets(), '/assets/runtime/serixa.js'); ``
If you moved the file to a different path or CDN, update this URL to match.
Symptom: you called ->onClick('someHandler') or similar, the data-serixa-on-click="someHandler" attribute appears in the rendered HTML, but nothing happens when clicked.
Cause: fluent DOM event methods (onClick, onChange, onInput, onSubmit, onFocus, onBlur, onKeyDown, onKeyUp) only emit data-serixa-on-* attributes. They do not register a JavaScript function for you. Something still has to call Serixa.on('someHandler', function (event) { ... }) in your own script.
Fix:
``html <script> Serixa.on('someHandler', function (event) { // your logic }); </script> ``
Modal, Dropdown, Tabs, Accordion, Toast), you don't need onClick at all — use the widget's own data-serixa-* wiring (data-serixa-open-modal, data-serixa-show-toast, …) as shown in interactive-components.md. Those are bound automatically by the runtime's built-in modules; custom onClick handlers are for your own app logic, not for opening framework widgets.Symptom: composer install hangs, or disk/IDE tooling (search, file watchers, backups) becomes extremely slow or appears to hang, when a SERIXA app lives inside a clone of the framework itself (e.g. framework/my-app/).
Cause: apps generated with a path repository pointing at the framework use a symlinked vendor/serixa/framework. If the app directory is also inside the framework tree, that symlink points back into a parent directory, and any tool that recursively walks the filesystem (naive LOC counters, some IDE indexers, find/grep -r) can loop through vendor/serixa/framework/<app>/vendor/serixa/framework/... indefinitely.
Fix:
``bash cd .. serixa new blog ``
serixa new warns you about this automatically if you run it from inside the framework tree.
validation/ and playground/ apps do), exclude vendor/ from recursive scans and restrict any LOC/search tooling to pages/, components/, layouts/, public/, config/.composer.json away from the path repository to a real version constraint (see deployment.md) — this removes the symlink entirely.Symptom: an InvalidArgumentException like:
Unknown theme component "buton".or
Invalid button theme state: variant="huge" size="md". Allowed variants: primary, secondary, danger, ghost. Allowed sizes: sm, md, lg.Cause: DefaultTheme::classes($component, $state) only knows a fixed set of component keys and, for many widgets, a fixed set of allowed prop values (checked via assertOption() on the widget or validated inside the theme). This is intentional — a typo or unsupported variant fails loudly at render time instead of silently rendering with no classes.
Fix:
serixa make:theme), make sure it handles every component key your app's widgets use — ThemeInterface::classes() is expected to either return classes or throw, not return an empty array silently.->color('huge')), not for data your users type into a form.make:* generation refused {#duplicate-make-commands}Symptom:
Error: Refusing to overwrite existing file: /path/to/pages/ArticlesPage.php
Duplicate generation blocked — rename the target or delete the existing file first.Cause: make:page, make:component, make:layout, make:theme, and make:plugin never overwrite an existing file. This protects hand-written edits from being silently discarded by a repeated command.
Fix: rename the class you're generating, or delete/rename the existing file first, then re-run the command.
Symptom: composer install fails with something like "could not find package serixa/framework" or resolves an unexpected version, right after serixa new.
Cause: the generated composer.json has a path repository whose url is the framework directory detected at generation time:
"repositories": [
{
"type": "path",
"url": "D:/yasas/PersonalProjects/Serixa",
"options": { "symlink": true }
}
]If you move the app to a different machine, or the framework clone moves/is deleted, this path is stale.
Fix:
url to point at wherever you cloned SERIXA locally, or switch to a version constraint if you don't need local development against the framework source: ``json "require": { "serixa/framework": "^0.11" } ``
(remove the repositories block once you do this).
composer install (or composer update) after changing the path.examples/*.php or the validation/ sample apps in the framework repo.