The fix is to skip the zip archive entirely. Create a blank Perspective view, hold Shift, right-click the view in the Project Browser, and select Paste JSON. The Designer rebuilds the view from the clipboard. Hand-editing a view export and re-zipping it fails because the project importer reads the archive's internal resource structure, and pasted text does not change that structure. The sections below build the view up in order. Each one ends with the check that proves it before you move on.
JSON Shape: View Definition vs Component Definition
The term view JSON means the complete serialized definition of a Perspective view. It is an object with the top-level keys custom, params, props, and root. The term component JSON means a single component subtree. It is an object whose top-level keys are the component's own fields, such as type, meta, props, and optionally children and position.
A blank view created with a flex root serializes to this:
{
"custom": {},
"params": {},
"props": {},
"root": {
"meta": { "name": "root" },
"props": { "direction": "column" },
"type": "ia.container.flex"
}
}
Shared JSON can be either shape. The shape decides where it gets pasted:
| Top-level keys in shared text | What it is | Paste target |
|---|---|---|
root present, plus params/props/custom
|
Full view | The view node in the Project Browser |
type and meta at top level, no root
|
Single component (and its children) | A container in the view's component tree |
| Array of component objects | Multiple components | A container in the view's component tree |
Check 1: Copy the shared text into any JSON validator. Expect the text to parse with no errors, and expect the top-level keys to match one row of the table. Text copied from a web page often carries typographic quotes or trailing characters that break parsing. Replace curly quotes with straight quotes before continuing.
Target View Creation
Paste into a new, empty view rather than a view with existing work. A view-level paste replaces the view's definition, including its params and custom properties.
- In the Project Browser, expand Perspective > Views.
- Right-click the destination folder and create a new view. Give it the final name and path you want, because other views and page configurations reference it by path.
- Accept any root container type. The pasted
rootobject overwrites it with whatevertypethe shared JSON specifies. - Save the project so the view exists as a committed resource before you modify it.
Check 2: Expect the new view to appear in the Project Browser under the chosen folder, and expect it to open on an empty canvas.
Paste JSON Operation
The Paste JSON entry is hidden from the normal context menu. It appears only when you hold Shift while right-clicking. The same Shift+right-click menu on a view also exposes Copy JSON, which is how the shared JSON was produced in the first place.
- Copy the validated JSON text to the clipboard.
- Hold Shift and right-click the new view's node in the Project Browser, not the canvas.
- Select Paste JSON.
- Open the view if it is not already open.
For component JSON (see the table above), open the target view instead. Then Shift+right-click the destination container in the component tree and paste there. The pasted components become children of that container.
Check 3: Expect the canvas to render the shared layout. Expect the component tree to show the same component names as the meta.name values in the JSON. Expect the Property Editor on the view node to list any params and custom keys from the source. If nothing changes, the clipboard held invalid JSON or a component-shaped object was pasted at the view level. Return to Check 1.
Dependency Resolution After Paste
View JSON carries references, not the things it references. A view that renders correctly on the author's gateway can show errors on yours because of missing dependencies:
| Reference in JSON | Symptom when missing | Resolution |
|---|---|---|
Embedded view path (props.path on an embedded-view component) |
Blank or error box where the child view should render | Import or recreate the child view at that exact path, or edit the path |
Style classes (props.style.classes) |
Components render with default styling | Create matching style class resources or remove the class names |
| Tag paths in bindings | Bad-quality overlay on bound components | Point bindings at tags that exist on your tag provider |
| Named queries, scripts, project library functions | Binding or script errors in the Designer output console | Recreate the resource or rewrite the binding |
| Expression functions or component types supplied by an add-on module | Expression errors, or components that do not render | Install the same module on your gateway |
JSON from a module's documentation or example pages frequently depends on that module's expression functions. Such a view pastes cleanly, but its bindings fail until the module is installed and licensed on the gateway serving the Designer.
Check 4: Open the Designer output console and select each bound component. Expect no binding errors and no bad-quality overlays. Each remaining error names the missing resource, tag, or function to fix.
Zip Import Failure Mode
A Designer project export is not a JSON file with a zip wrapper. It is an archive of resource folders. Each view is a folder under the Perspective views tree. That folder holds view.json plus a resource metadata file (resource.json) that describes the resource, and usually a thumbnail. The importer places resources according to the folder paths inside the archive. It does not use the zip filename.
The following practices fail, and should not be used:
- Renaming the zip file. This changes nothing the importer reads. The resource path inside the archive stays the same.
-
Overwriting
view.jsoninside a fresh export. The resulting archive can import with no visible new resource. The path may collide with the existing empty view, or the metadata may not match the edited content. -
Zipping a loose
view.json. Without the resource folder structure and metadata, the importer has nothing to place.
Reserve zip import for archives that the Designer itself exported, unmodified, with the full resource folder structure. For raw JSON text, Paste JSON is the correct path.
Check 5: Delete any stray views created by earlier import attempts, then save. Expect exactly one copy of the view in the Project Browser, at the path chosen in the target view step.
End-to-End Verification
- Check 6: Save the project. Expect the save to complete with no conflict dialog.
- Check 7: Shift+right-click the view and select Copy JSON, then compare it against the source text in a diff tool. Expect the structure and property values to match. Only formatting differences, and any edits made during dependency resolution, should appear.
- Check 8: Enter preview mode in the Designer. Expect bindings to update and any interactive components to respond.
- Check 9: Add the view to a page configuration, or embed it in an existing page. Launch a Perspective session in a browser. Expect the view to render at runtime with the same layout seen in the Designer, and expect no errors in the session's browser console or the gateway logs.
FAQ
Can I paste component JSON into an existing view without replacing it?
Yes. Open the view, Shift+right-click the destination container in the component tree, and select Paste JSON. The components are added as children of that container. The rest of the view is left intact.
Does Paste JSON on a view overwrite its params and custom properties?
Yes. A view-level paste replaces the whole definition, including params, custom, props, and root. Paste into a new blank view, or run Copy JSON on the existing view first to keep a backup.
Can I import a view from a zip file instead of pasting JSON?
Only when the zip is an unmodified Designer export with its resource folder structure and metadata intact. Editing view.json inside the archive or renaming the zip does not work reliably, so use Shift+right-click > Paste JSON for raw JSON text.