Project Metadata
wallpaperEnginePlugin() emits project.json as a Vite asset. It combines generated build facts with source-controlled author metadata and preserves editor-owned fields from previous output.
import { wallpaperEnginePlugin } from 'wallpaper-engine/plugin';
wallpaperEnginePlugin({ title: 'Night Sky', schemeColor: '#5994ff', metadata: { description: 'An animated night sky.', preview: 'preview.jpg', tags: ['Landscape'], },});Options
Section titled “Options”| Option | Type | Default / role |
|---|---|---|
title |
string |
Required Wallpaper Engine title |
file |
string |
Entry HTML path; defaults to 'index.html' |
schemeColor |
string |
Color.js syntax normalized into the reserved index-free general.properties.schemecolor; previous editor state is the fallback |
properties |
Property record | User properties written under general.properties |
localization |
Localization map | Labels written under general.localization |
supportsAudioProcessing |
boolean |
Defined value overrides bundle-call detection |
metadata |
WallpaperProjectMetadata |
Source-controlled description, preview, tags, ratings, and visibility |
metadataFile |
string |
Non-null, non-array top-level JSON object resolved from Vite’s final project root |
projectLink |
WallpaperProjectLinkOptions |
Persistent link to written output; see Project Links |
minify |
boolean |
Build output defaults to minified JSON; false uses tab indentation |
devtools |
boolean |
Development overlay; defaults to true, always omitted from production |
Generated shape
Section titled “Generated shape”The plugin always generates these core fields:
{ "file": "index.html", "title": "Night Sky", "type": "web"}It generates general only when at least one applicable field exists:
{ "general": { "properties": {}, "localization": {}, "supportsaudioprocessing": true }}properties are normalized with zero-based index and order according to record insertion order; explicit values win. supportsaudioprocessing is included only when an explicit true or emitted-bundle detection enables it. A false/absent result does not write a false field.
Written build JSON is one line by default. Set minify: false to use tab indentation. Serve mode does not emit project.json.
Ownership and precedence
Section titled “Ownership and precedence”Merge precedence is exact:
previous output < metadata file < defined metadata options < generated fields- Existing
dist/project.jsonis the lowest-priority preservation source. metadataFilereplaces colliding top-level keys from previous output.- Each
metadatafield replaces lower-priority values only when it is notundefined. - Generated
file,title,type, and ordinarygeneralfields always win. - A defined
schemeColoroption wins over every previousgeneral.properties.schemecolorvalue. When the option is omitted and the source property schema does not define that key, a valid editor-managed value is carried into regenerated properties.
Merging is otherwise top-level and shallow. general is removed from preservation sources and regenerated from plugin options and bundle audio detection. Put localization and ordinary properties in their defined options rather than an editor-owned general object.
Unknown top-level fields survive from previous output or a metadata file unless a higher source replaces them. This allows Wallpaper Engine editor state to coexist with build-owned fields.
Metadata files
Section titled “Metadata files”wallpaperEnginePlugin({ title: 'Night Sky', metadataFile: 'wallpaper-engine.metadata.json',});The path resolves from Vite’s final root. The file is required when configured and must contain valid JSON with a non-null, non-array top-level object. Missing, unreadable, malformed, or wrong-shaped input fails the build with a specific error rather than silently discarding publishing state.
Preview paths and restoration
Section titled “Preview paths and restoration”A non-empty final preview must be a safe project-relative file path inside the project output. preview: '' is preserved and skips path validation and restoration. For non-empty paths, the plugin rejects:
- POSIX, Windows drive, and UNC absolute paths.
- Traversal that resolves outside the project directory.
.or another value that does not identify a project file.
Backslashes are normalized for preview lookup and emitted asset filenames, but the preview string serialized in project.json is preserved verbatim. Use forward slashes in metadata when that serialized form is required. During a written build, a non-empty final preview must come from one of these sources:
- An asset already emitted into the Vite bundle at the final path.
- A matching file under Vite’s final
publicDir. - The previous build output, captured before Vite cleans
outDir.
When restoring from previous output, the plugin reads the file as bytes and emits those exact bytes back to the same normalized relative path. It does not decode, resize, or re-encode the preview.
A clean clone or CI job has no previous output. Keep the preview under publicDir at the exact final path, or explicitly emit/configure an asset whose final bundle fileName exactly matches metadata.preview.
The build lifecycle follows Vite’s resolved root, publicDir, build.outDir, and build.write configuration. See Vite’s build guide for those host-owned settings.
Source
Section titled “Source”Generation and preservation are implemented in src/plugin/index.ts.
Next steps
Section titled “Next steps”Link safe written output with Project Links, then follow the Workshop Workflow to preserve editor state.