Upgrade to LightNet v4
This is the migration guide for upgrading an existing project to the latest LightNet v4 release.
1. Update platform prerequisites
Section titled “1. Update platform prerequisites”Upgrade to Astro v6
Section titled “Upgrade to Astro v6”LightNet now targets Astro v6.
Breaking changes
Section titled “Breaking changes”- Sites using LightNet should upgrade their Astro dependency to v6.
Migration
Section titled “Migration”- Update your site with:
npx @astrojs/upgrade- Follow the Astro v6 migration guide for any manual follow-up steps:
https://docs.astro.build/en/guides/upgrade-to/v6/
Remove @astrojs/tailwind from your site
Section titled “Remove @astrojs/tailwind from your site”LightNet no longer depends on @astrojs/tailwind. That integration was previously needed to support Tailwind CSS v3, but Astro v6 no longer supports Tailwind CSS v3 through @astrojs/tailwind. LightNet now provides a built-in Tailwind implementation instead.
Reference:
https://github.com/withastro/astro/issues/15824
Migration
Section titled “Migration”If your site still lists @astrojs/tailwind in its package.json, remove it from your dependencies.
Reconfigure DaisyUI manually if you use it
Section titled “Reconfigure DaisyUI manually if you use it”DaisyUI was removed from LightNet’s built-in Tailwind configuration. LightNet no longer injects DaisyUI plugin/theme settings automatically.
Breaking changes
Section titled “Breaking changes”- DaisyUI styles are no longer generated by default.
- Sites using DaisyUI classes (
dy-prefixed classes) must configure DaisyUI themselves.
Migration
Section titled “Migration”If your site uses DaisyUI utilities/components, install and configure DaisyUI in your project Tailwind config.
This is how LightNet used to configure DaisyUI:
import daisyui from "daisyui";
const primary = "#E6B15C";
export default { plugins: [daisyui], daisyui: { themes: [ { lightnet: { primary, secondary: primary, accent: primary, neutral: "#030712", error: "#9f1239", "base-100": "#f9fafb",
"--rounded-box": "0.375rem", // border radius rounded-box utility class, used in card and other large boxes "--rounded-btn": "0.375rem", // border radius rounded-btn utility class, used in buttons and similar element "--rounded-badge": "0.375rem", // border radius rounded-badge utility class, used in badges and similar "--tab-radius": "0.375rem", // border radius of tabs }, }, ], base: false, // applies background color and foreground color for root element by default utils: true, // adds responsive and modifier utility classes logs: false, // Shows info about daisyUI version and used config in the console when building your CSS prefix: "dy-", },};If your site does not use DaisyUI classes, no action is required.
2. Update the admin integration
Section titled “2. Update the admin integration”Replace Decap admin with Sveltia admin
Section titled “Replace Decap admin with Sveltia admin”An experimental LightNet administration UI based on Sveltia CMS was added. This replaces the previous experimental Decap-based admin integration.
Breaking changes
Section titled “Breaking changes”@lightnet/decap-adminis replaced by@lightnet/sveltia-admin.- The admin integration no longer accepts a
languagesoption; languages are resolved from LightNet config.
Migration
Section titled “Migration”- Replace package imports.
// beforeimport decapAdmin from "@lightnet/decap-admin";
// afterimport lightnetSveltiaAdmin from "@lightnet/sveltia-admin";- Update integration setup and remove
languagesoption.
// beforeintegrations: [ decapAdmin({ languages: ["en", "de"], }),];
// afterintegrations: [lightnetSveltiaAdmin({})];Remove the imagesFolder option
Section titled “Remove the imagesFolder option”The imagesFolder option was removed from @lightnet/sveltia-admin. Image fields now always use the content-adjacent images directory.
Breaking changes
Section titled “Breaking changes”imagesFolderis no longer a valid integration option.- Passing
imagesFoldernow throws during Astro integration setup. - Sveltia image upload paths are fixed to
images.
Migration
Section titled “Migration”- Remove
imagesFolderfrom yourlightnetSveltiaAdmin(...)config.
// beforelightnetSveltiaAdmin({ imagesFolder: "_images",});
// afterlightnetSveltiaAdmin({});- Rename the media image folder to
src/content/media/imagesif needed.
# beforesrc/content/media/_images/
# aftersrc/content/media/images/- Update image paths in media content entries.
// before{ "image": "./_images/my-image.jpg"}// after{ "image": "./images/my-image.jpg"}3. Migrate localization and configuration
Section titled “3. Migrate localization and configuration”Move locale access to Astro.locals.i18n.currentLocale
Section titled “Move locale access to Astro.locals.i18n.currentLocale”LightNet no longer injects Astro i18n routing config during integration setup. Locale-aware code should now read the active locale from Astro.locals.i18n.currentLocale.
Breaking changes
Section titled “Breaking changes”- LightNet no longer configures Astro
i18n(locales,defaultLocale,routing) for you. - Code paths using
Astro.currentLocalemust switch toAstro.locals.i18n.currentLocale.
Migration
Section titled “Migration”- Update locale access in pages and components to read from
Astro.locals.i18n.
---// beforeconst currentLocale = Astro.currentLocale
// afterconst { currentLocale } = Astro.locals.i18n---- If your project relies on Astro
i18nrouting for routes outside LightNet, define it explicitly inastro.config.*.
LightNet still rewrites / to /{defaultLocale}.
This is the Astro i18n config LightNet used to generate:
export default defineConfig({ i18n: { defaultLocale: "en", locales: ["en", "de"], routing: { redirectToDefaultLocale: false, prefixDefaultLocale: true, fallbackType: "rewrite", }, },});Convert labels to explicit inline locale maps
Section titled “Convert labels to explicit inline locale maps”Label fields were changed from implicit string values to explicit inline locale maps across config and content. Translation lookups with t(...) now treat string inputs strictly as translation keys.
Example label map:
{ "label": { "en": "Hello", "de": "Hallo" }}Breaking changes
Section titled “Breaking changes”- Label fields no longer accept plain strings (including
x.*orln.*values). - Label fields must be locale maps scoped to configured site locales.
t("...")now treats string input strictly as a translation key and throws when missing.
Updated fields:
- Config:
title,logo.alt,mainMenu[].label - Content:
languages.label,categories.label,media-collections.label,media-types.label,media[].content[].label,media-types.detailsPage.openActionLabel
Validation rules:
- Locale-map keys must be valid BCP-47 tags.
- The default site locale is required.
- Other configured site locales are optional.
- Locale keys must be configured site locales.
- Extra locale keys are rejected.
- Label values must be non-empty strings.
Migration
Section titled “Migration”- Convert label strings to locale maps in config.
// before{ "title": "My Library", "mainMenu": [{ "href": "/about", "label": "About" }]}
// after{ "title": { "en": "My Library" }, "mainMenu": [{ "href": "/about", "label": { "en": "About" } }]}- Convert content label fields to locale maps.
// before{ "label": "Books"}
// after{ "label": { "en": "Books", "de": "Bücher" }}- Ensure keys passed as strings to
t(...)exist in translation files.
Drop the x. prefix from custom translation keys
Section titled “Drop the x. prefix from custom translation keys”User translation keys no longer need the x. prefix. You can now use direct keys like site.title and home.bbq.title while built-in LightNet keys remain under ln.*.
Example:
# beforex.home.title: "Welcome"
# afterhome.title: "Welcome"Breaking changes
Section titled “Breaking changes”- None.
4. Migrate content models
Section titled “4. Migrate content models”Add explicit type to media content entries
Section titled “Add explicit type to media content entries”Media item content entries now use explicit typed objects so storage intent is clear (upload vs link).
Examples:
{ "type": "upload", "url": "/files/example.pdf", "label"?: ... }{ "type": "link", "url": "https://example.com/file.pdf", "label"?: ... }
Breaking changes
Section titled “Breaking changes”contententries are expected to use explicittypevalues (uploadorlink).
Migration
Section titled “Migration”Update media content entries to include type.
// before{ "content": [ { "url": "/files/my-book.pdf", "label": { "en": "Read PDF" } } ]}
// after{ "content": [ { "type": "upload", "url": "/files/my-book.pdf", "label": { "en": "Read PDF" } } ]}Use type: "upload" for site-managed files and type: "link" for external URLs.
Move collection membership into media-collections
Section titled “Move collection membership into media-collections”Collection ownership was reversed from media[].collections to media-collections[].mediaItems. Collections now own membership and order directly.
Breaking changes
Section titled “Breaking changes”mediaentries no longer support thecollectionsfield.media-collectionsentries now define membership usingmediaItems.- Collection ordering is now defined by the order of IDs in
mediaItems.
Migration
Section titled “Migration”- Remove
collectionsfrom each media item.
{ "title": "My book", "collections": [ { "collection": "learn-series" }, { "collection": "featured", "index": 2 } ]}
// after{ "title": "My book"}- Add media membership and order to each media collection.
{ "label": { "en": "Learn Series" }, "mediaItems": ["my-book--en", "another-item--en"]}If you previously used per-item index, convert that ordering into mediaItems array order.
Move detailsPage.coverStyle to coverImageStyle
Section titled “Move detailsPage.coverStyle to coverImageStyle”Deprecated media-types.detailsPage.coverStyle support was removed. Cover styling now belongs at top-level coverImageStyle.
Breaking changes
Section titled “Breaking changes”detailsPage.coverStyleis no longer supported.- Automatic schema migration from
detailsPage.coverStyletocoverImageStylewas removed.
Migration
Section titled “Migration”Move cover style values to top-level coverImageStyle in each media type file.
// before{ "detailsPage": { "layout": "default", "coverStyle": "book" }}
// after{ "coverImageStyle": "book", "detailsPage": { "layout": "default" }}commonId is now optional for media items
Section titled “commonId is now optional for media items”Media items no longer require commonId.
- In
lightnet, media item schema validation now accepts entries withoutcommonId. - Translation lookup now treats missing
commonIdas standalone and returns no translations for that item. - In
@lightnet/sveltia-admin, theCommon IDfield is now optional in the media item editor.
5. Update component and icon APIs
Section titled “5. Update component and icon APIs”Rename MediaGallerySection props
Section titled “Rename MediaGallerySection props”MediaGallerySection props were renamed and layout defaults were updated to improve API clarity.
Example updated usage:
<MediaGallerySection items={items} itemWidth="narrow" layout="grid" />Breaking changes
Section titled “Breaking changes”layout(old item style prop) was renamed toitemWidth.- Old
layoutvalues ("book" | "video" | "portrait" | "landscape") were removed. itemWidthnow supports"infer" | "narrow" | "wide"and defaults to"infer".viewLayoutwas renamed tolayout.- Default layout is now
"carousel". - Old prop names
layout(style meaning) andviewLayoutare no longer supported. itemWidth="infer"uses the first 10 media items to choose a width:- more landscape images (
width > height) =>"wide" - otherwise =>
"narrow"
- more landscape images (
Migration
Section titled “Migration”Update component usage to the new prop names and values.
<!-- before --><MediaGallerySection items={items} layout="book" viewLayout="grid" />
<!-- after --><MediaGallerySection items={items} itemWidth="narrow" layout="grid" />
<!-- after (explicit inferred width, default behavior) --><MediaGallerySection items={items} itemWidth="infer" layout="grid" />coverImageStyle is now sourced from each media type configuration.
Switch custom icons to Lucide names
Section titled “Switch custom icons to Lucide names”Replace Material Design Icons with Lucide icons across LightNet.
LightNet now uses the Lucide icon set for a more consistent and modern visual language.
Migration
Section titled “Migration”Projects should update custom icons used in media types or with the <Icon /> component to Lucide icon names prefixed with lucide--.
Material Design Icons with the mdi-- prefix are now deprecated and will be removed in the next major release.