-
Require Volt 0.20. Volt now reads JavaScript formatter options from the
:voltkey of.formatter.exsand raises on a keyword list underconfig :volt, :format. Move a site's options:# .formatter.exs [ plugins: [Astral.Formatter, Volt.Formatter], volt: [semi: true, single_quote: false] ]mix astral.installwrites them there. See Volt's changelog for the rest of 0.20, including externals staying as imports in ES module output.
-
With Volt 0.20, saving a page, layout, component or collection entry reloads only the open pages whose HTML changed, instead of every page.
-
Pages can be updated in place instead of reloaded, keeping scroll position and mounted islands, with Volt's opt-in setting:
config :volt, :server, morph: [preserve: "[data-astral-island]"]
- The basic example resolves its dependencies and passes
mix checkagain. Its lockfile predated Volt 0.19, and its lint plugins were atoms, which Volt 0.19 rejects.
- An image source rewritten in place while
mix astral.devruns now produces variants of its new pixels. libvips cached the decoded file by name, so the variant got a new name from the new content hash but kept the old pixels, and a later build copied that stale variant from the image cache. Sources are now decoded from the bytes that were hashed.
- Document MDEx plugins in
markdown(plugins: [...]). They already ran on pages and collection entries; a test now covers it.
- A
<script>or<style>in an.astraltemplate is rendered where it is written, as in any HEEx template. To build one with Volt, mark it with:type={Astral.Script}or:type={Astral.Style}, following Phoenix's<script :type={Phoenix.LiveView.ColocatedJS}>. Add:typeto existing blocks that should stay Volt modules.
mix astral.devapplies changes toastral.config.exsand the project's Elixir sources without a restart. A config change starts the server with the new config, and a source change recompiles the project. Open pages reload once the change is in. A broken config or a compile error shows in Volt's error overlay, titled "Config error" or "Compile error", and leaves the running server in place.
- Require Volt 0.19.3, which accepts compiler diagnostic structs in its error overlay and resolves OXC runtime helpers.
- Locate syntax and compile errors in development at the file and line they carry, without the loader's stacktrace.
- Require Volt 0.19. Lint
:plugins,:env, and:globalsinconfig :volt, :linttake string names, such asplugins: ["typescript", "jsx-a11y"]; see Volt's changelog. - Require MDEx 0.14.1 and Lumis 0.10 for syntax highlighting. Lumis 0.10 installs each language's parser as its own
lumis_wasm_*package; add one for every language your code fences use.
- Show development render errors in Volt's error overlay instead of crashing the request with an empty 500. Exceptions raised while rendering
.astralpages, layouts, and components are reported withVolt.HMR.error/3with their source file, line, frame, and stacktrace, and the overlay clears once the page renders again. The error page keeps the error as plain text for clients without JavaScript. - Report the component's own
.astralfile in stacktraces instead of the page or layout that rendered it.
- Add site-scoped
markdownoptions for MDEx rendering across pages, collections, and feeds, including optional Lumis syntax highlighting with light/dark themes. - Add
Astral.Formatterformix format: format Elixir setup blocks, HEEx templates, and embedded JavaScript/TypeScript through Volt. The installer configures the plugin and.astralinputs for new and existing projects.
- Preserve whitespace between highlighted code tokens and inline elements when injecting the development HMR client.
- Add
Astral.Plugin.LLMsfor metadata-drivenllms.txtgeneration in builds and development, with automatic discovery, exclusions, curated sections, and external links. New starters enable it with the project title.
- Include Volt's shared browser declarations in starter TypeScript configurations instead of generating application-local
ImportMetadefinitions.
- Require explicit
islands do component :vue, "path.vue" enddeclarations for runtime-selected components that cannot be discovered from literal template references.
- Replace generated TypeScript island files in
assets/.astral/islandswith shared virtual component entries; serialize instance props and hydration settings in HTML. - Compose development assets through one supervised Volt session and use Volt's complete production build API.
- Normalize configured asset entries to lists and support multiple entries.
- Build browser assets before rendering documents so asset URLs can be used in HTML, island props, and generated data routes without rendering pages twice.
- Include production island stylesheet dependencies in the active document head, including dependencies first encountered inside inert slot templates.
- Mount late-appearing nested islands when another instance has already loaded their shared component entry.
- Respect explicitly disabled Tailwind configuration during builds and development startup.
- Reject colliding destinations within pages or generated routes instead of silently overwriting documents, while preserving generated-route precedence over pages.
- Coordinate concurrent first renders of a template so requests do not fail while its module is being compiled.
- Resolve component-relative SVG references from the component file while preserving the caller's source context in slots.
- Require Bandit 1.12.5 or later to address HTTP/2 header validation and connection-window starvation (CVE-2026-75484, CVE-2026-74836).
- Require Igniter 0.8.4 or later to prevent terminal escape injection through package metadata in installer confirmation prompts (CVE-2026-82584).
- Reject symlinked document and image destinations, including copied public links, to prevent generated output from writing outside the output directory.
- Reject symlinked output-directory parents within the project before clearing the previous build.
- Require Volt 0.18 for the shared build and supervised development-session APIs.
- Exclude generated
assets/.astral/browser entries from the formatter configuration created by the Astral installer.
- Prevent generated client-island entries from causing repeated full-page reloads in the development server.
- Update Volt to 0.17.11 for configurable watcher exclusions and normalized filesystem events.
- Added Astral- and Volt-focused
AGENTS.mdguidance to starter projects while preserving existing project instructions. - Added starter
.gitignorecoverage for static output, browser dependencies, generated island entries, and local environment files.
- Starter pages, layouts, and generated README files now use the Mix application name instead of generic Astral branding.
- Replaced Mix's placeholder README in new sites with concise Astral development and build instructions while preserving existing project documentation.
- Updated setup documentation with the one-command
mix igniter.new my_site --install astralproject creation flow.
- Added nested hydrated island support for islands rendered inside another island's slot.
- Hardened island tests for nested JSON-safe props, repeated same-component mounts, async mount idempotency, and static browser integration coverage.
- Reused content-addressed compiled template modules instead of creating a new BEAM module and atom on every render.
- Hardened public-file, image-cache, island-component, page, plugin-route, and output-directory path boundaries.
- Prevented unsafe explicit island IDs and collisions between explicit and generated island IDs.
- Made
client={:media}islands hydrate when their media query starts matching after page load. - Made React island mounts synchronous so nested island entry scripts are activated reliably.
- Made
mix astral.devreject invalid command-line options consistently withmix astral.build.
- Documented and tested mixed Vue, Svelte, React, and Solid islands on the same page, including repeated same-framework islands and mixed client directives.
- Added Solid island build support using
.solid.jsxand.solid.tsxcomponent filenames.
- Production island assets now build as ES modules and share common framework/runtime chunks through Volt 0.15.5.
- Moved island browser tests under
test/astral/islands/browser/and added Elixir build/integration coverage for mixed framework islands. - Updated Volt to 0.15.5.
- Added Volt browser tests for island runtime behavior and framework adapters across React, Vue, Solid, and Svelte.
- Updated Volt to 0.15.2 for package import specifier resolution used by Svelte's browser runtime internals.
- Rebuilt the configuration DSL on the shared
dslpackage while preserving existingsite do ... endsyntax and generated route behavior.
- Preserved external
<script src="...">tags in.astraltemplates while still extracting inline script blocks into Volt modules.
- Replaced the
collections do ... endconfig wrapper with top-levelcollectiondeclarations.
- Replaced the top-level
plugins [...]config declaration with singularplugindeclarations for cleaner config files.
- Dynamic route params rendered in
@paramsare now atom-keyed, matching setup-declared route params and schema-normalized entry data.
- Top-level
astral.config.exsdeclarations for site configuration, preserving legacysite do ... endsupport.
- Starter scaffolding, the basic example, and documentation now use the top-level config style.
- Static HEEx children for client islands, passed to framework runtimes through the default slot/children channel.
- Server-rendered Iconify icons through PhoenixIconify's
<.icon>component in.astraltemplates. - Inline local SVG files through
<.svg src="..." />, resolved with Volt asset aliases and rendered as HTML-safe SVG. - Phoenix-shaped
getdeclarations inastral.config.exsfor one-off generated static routes, with Plug-compatible middleware viaplug. - A userland head metadata component pattern in the basic example and pages/layouts guide.
- Root custom 404 pages (
pages/404.{md,html,astral}) that build todist/404.htmland return 404 in development. - Documentation and tests for deterministic static output precedence: public files, then pages, then generated routes.
- A custom 404 page in the basic example site.
- Clearer content collection documentation for schema defaults and userland tag page patterns.
- Setup-declared dynamic
.astralpage paths through strictAstral.Route.Pathvalues and thepath/1setup helper. - Clearer develop/build/configuration docs covering dev server options, static build preview expectations, and metadata placement.
- Editor setup, TypeScript, and environment variable guides that map Astral's Elixir site layer to Volt browser tooling.
- Clearer plugins/integrations documentation separating Astral site plugins from Volt browser asset plugins.
- Clearer routing, static endpoint, and middleware-scope documentation after auditing Astro's routing/endpoints/middleware guides.
- Navigation documentation covering current i18n, prefetch, and view-transition boundaries.
- Styling and browser-code documentation covering current CSS, font, syntax-highlighting, script, and framework-island boundaries.
- Markdown, content, and data-fetching documentation covering current MDX, Markdown import, content loader, and live collection boundaries.
- Server/runtime documentation covering current on-demand rendering, server island, action, session, and route caching boundaries.
- Deployment documentation covering current static-host deployment and future adapter boundaries.
- Backend, authentication, and testing documentation covering current composition boundaries.
- Image documentation covering current build-time image service and future adapter/CDN boundaries.
- Collection helpers, feed entry authors/dates, and collection sitemap dates now use schema-normalized
entry.datainstead of falling back to raw string-keyed frontmatter metadata. - Schema-less collections now expose empty normalized
entry.datawhile preserving raw frontmatter inentry.metadata.
- Dynamic file routes with route diagnostics.
- Ecto-style content collection schema fields.
- Markdown rendering with Astral HEEx components.
- Optimized local and remote image pipeline with image, picture, figure, metadata, Markdown image, dev-server, and collection image field support.
- Client-only islands for Vue, Svelte, React, and Solid with framework-specific HEEx components.
- Island client directives for
:load,:idle,:visible, and:media. - JSON-safe island props handling through JSON-shaped values, JSONCodec structs, and Jason encoders.
- Type-aware Volt JavaScript checks for Astral island runtime assets.
- Vue and React islands in the basic example site.
- All Volt-supported island adapters are enabled by default.
- Astral island runtime assets are maintained as TypeScript files under
priv/islands.
- HEEx-first
.astraltemplates for pages, layouts, and local components. - Parser-backed
.astral<style>and<script>extraction through Volt embedded modules. - Example site pages, layouts, and components that dogfood
.astraltemplates.
Initial Astral development release.
- Static HTML and Markdown build pipeline.
- Elixir
astral.config.exssite DSL. - MDEx-backed Markdown and frontmatter support.
- EEx layouts with page, metadata, route, and site assigns.
- Per-page layout selection and layout disabling.
- Plug/Bandit development server composed with Volt.
mix astral.devandmix astral.buildtasks.Astral.asset_path/2for Volt-managed layout assets.examples/basicrunnable site with TypeScript, CSS, layouts, Markdown, public files, and Volt lint/format configuration.- Igniter-powered starter site scaffolding through
mix astral.new,mix astral.install, andmix igniter.install astral.