What's new in Magnolia headless?
Magnolia in action
Take 12 minutes and a coffee break to discover how Magnolia can elevate your digital experience.
Hey devs, this one is for you. While we’re always making improvements to our product, some key milestones have been reached lately which we are excited to share with you. It’s time to highlight some of these updates. For those of you who might not be pouring through the release notes with each new release, we want to make sure that you know about them so you can take advantage of them in your projects.
Let's dive right in with the big ones.
The big ones
This first batch is about bringing existing popular freemarker-based features to the Visual SPA Editor.
Component inheritance on headless
This has been the single most popular request from Magnolia veterans who know the freemarker templating system - this feature has existed for years on freemarker. For you newbies, you are probably trying to imagine what this even means. Component inheritance is a really powerful feature that automatically includes a component on all child pages. Actually a more precise name would be "area inheritance", because an area plus all its components are included in the child pages. The components are only editable on the "top" page.
Component inheritance is often used for header and footer content. It's also useful for promotions and other "side bar" style content that you want to show up throughout a section of a site. It's a great author experience and eliminates any duplication of content.
Of course these use cases can also be handled purely in the frontend by making specific REST requests to get certain content, like a header. At Magnolia we don't want to create new ways of doing things that developers already have their own ways of doing. But you convinced us that even in headless projects this feature really helps with your actual projects.
Component auto-generation on headless
This has been another hot request from the Magnolia experts. With this longstanding freemarker templating feature developers can configure components to be automatically generated in an area. This is now supported on headless visual SPA editor projects as well.
With this feature you can make things more clear for authors, and save them time with some automation. A common use case is to have a page template with one or more areas that have auto-generated components. It is very intuitive for the author to work on that content, and now they just have to click on the area of the page that they want to edit, because the component is already there. You can even supply default content for those components.
Contrast this to the approach of putting a lot of fields directly into the page dialog - with that approach an author will have a harder time understanding how filling in a field there will impact the rendered page.
If you are interested in learning more about component auto-generation and how you can use this feature in your projects, check out our documentation.
Multiple page-editor apps on headless
You have always been able to create additional apps that include the page editor and function just like the OOTB (out-of-the-box) Pages app. Now this is possible in headless mode too. (Tech note: To do this, we have removed the assumption that the page editor always operates on the "website" repository, as it does in the Pages app. Now you can connect the visual SPA editor features to any repository.)
Customers use this capability to enable authors to manage different channels in different apps. For example, if a project includes managing creative content for digital signage in a department store, it's more clear to an author when there is a specific app called "Digital Signage". It would be confusing to manage digital signage and website content both in the OOTB Pages app.
Multiple page-editor apps with Light Development (Now in Beta)
OK. So we just promoted being able to create custom page-editor apps. But if you skim the above link, you'll see that it takes a bit of work and requires a Java module. But not for long! We are just wrapping up the ability to do this with just a few lines of configuration. It works like the content-type based apps.
This is the entire app definition for a new "signs" app.
!page-editor-app:signs
name: signs
Interested? We are looking for beta testers. Get in touch if you'd like to try it out.
You can just drop a note at the bottom of the Roadmap Card, and we'll be in touch.
Specify which properties to return in Delivery API
Another very popular request. This one is not just relevant for the visual SPA editor, but in any headless context. We pulled out the stops on this one and made it super-flexible in order to meet your use cases with a minimum of configuration on the endpoint.
On the config of the delivery endpoint you can take a white-list or black-list approach.
excludeProperties - Just specify which properties should not be returned.
properties - List the properties that should be returned, none of the other properties will be returned.
$type: jcrDeliveryEndpoint_v2
workspace: tourss
bypassWorkspaceAcls: true
excludeProperties:
- description
You can also use these on the referenceResolver configurations. This means you can now specify that you only want the "image" and "tagline" properties from the content item that is referenced, not all of its properties.
But we know that as a developer, sometimes you want to tune the response in a more dynamic way, via the request. So we also support configuring the content to return via new querystring parameters, "properties" and "excludeProperties". (Note: these are available only for the main content, not the referenceResolver content.)
https://demopublic.magnolia-cms.com/.rest/delivery/tours/v1/?excludeProperties=description
Those are the headlines. Cool huh? Now let's get into the nitty gritty.
Product brief: The Headless Accelerator
Speed up your headless projects with one set of Web Components and one unified workflow—for your entire customer experience. Download the Product Brief which offers you a design framework for your entire customer experience.
Delivery API
There are a number of smaller improvements in the delivery API.
Pages endpoint is simpler to configure with jcrPagesDeliveryEndpoint_v2
You used to have to supply some "boilerplate" configuration to get a deliveryEndpoint to function properly with the Pages App when using the `jcrDeliveryEndpoint_v2` endpoint.
Now you can use the `jcrPagesDeliveryEndpoint_v2` and you don't need to supply the nodetypes. This is sufficient:
$type: jcrPagesDeliveryEndpoint_v2
workspace: website
depth: 1
bypassWorkspaceAcls: true
systemProperties:
- mgnl:template
Control the depth of the response from a referenced node with depthInReferencedNode
This solves a problem where the delivery response will sometimes return much more content than you want. This one is a little subtle. The 'depth' referred to in 'depthInReferencedNode', is how many rounds of descendants should be returned in a resolved node. You can imagine that when the referenced node is a page, this can result in returning the entire page with all of its areas and components, which is usually way more than you want.
To prevent making a breaking change - the default value is -1 (meaning that it resolves all rounds of descendants.) We recommend setting it to the smallest value you need - for example 1 or 2.
...
references:
- name: depthExample
propertyName: targetPage
referenceResolver:
$type: jcrReferenceResolver
targetWorkspace: website
depthInReferencedNode: 1
The Query nodes response now returns the number of results in total
This was much requested and is useful in creating pagination UIs.
Case insensitive search with ILIKE.
Until now, all search operators were case sensitive. You can still use the LIKE operator which remains case sensitive - but now you can make case insensitive searches with the ILIKE operator. (Do you like the name?)
Filter on @path and @name
You guessed it - now you can also filter on the path and name pseudo properties.
Set the size threshold above which responses are not cached
Did you know that by default any response larger than 500kb (before compression) will not be cached? This could be causing a lot of unnecessary computation in returning REST responses, especially if they are doing a lot of referenceResolving. Maybe you are thinking that responses should not be that big - but consider that a 150kb response might be around 500kb uncompressed. Also, FYI, by default the cache will start invalidating entries once it has cached 10000 responses.
Well now you have fine-grained control since both of those things are now configurable.
Pro tip: use decoration to cleanly override the default configuration.
Use "cacheResponseThreshold" to set the size in KBs above which items will not be cached.
Use "resourceUnit" and "size" if you want to hold cache entries up to a maximum size instead of number of entries. For example- set the cache to only use 1 GB of memory total so you know you will never exhaust your RAM.
Frontend Helpers
The frontend helpers are the javascript packages that help connect your React, Angular, Vue or other framework to the page editor. Here's the latest improvements.
Fallback component
You can now configure a "fallback component" for your frontend projects. When the frontend helper library cannot find the frontend component associated with the Magnolia component returned in the delivery API response, it will render the fallback component instead of an error. This makes development easier and more forgiving. You are not forced to provision all of your frontend components ahead of time. Authors could even start entering content before your templates are ready. Also consider the case of a typo, or forgetting to set up the component mapping - you'll get the fallback component rendered instead of an unhelpful exception.
The libraries provide default fallback components out of the box - and it's easy for you to supply your own.
Simplify SPA boilerplate with getMagnoliaContext()
The new getMagnoliaContext method present in the frontend helpers libraries makes it easier and more consistent to wire up your frontend project to Magnolia.
Calling the command
const magnoliaContext = EditorContextHelper.getMagnoliaContext(requestUrl, spaRootNodePath, languages);
Gives you all these helpful values:
magnoliaContext = {
isMagnolia: true,
isMagnoliaEdit: true,
isMagnoliaPreview: false,
nodePath: /home/travel,
currentLanguage: 'en',
searchParams: { mgnlChannel: 'desktop', mgnlPreview: 'false', variants: 'all' },
search: '?mgnlPreview=false&mgnlChannel=desktop&variants=all&lang=en'
}
Updating libraries at a regular cadence
We've configured a regular scan of our libraries dependencies (Renovate bot) to ensure we keep up with vulnerabilities in our dependencies.
We've also instituted a policy to support the oldest supported versions of the framework libraries (React, Angular, Vue), to ensure that we don't unnecessarily force our customers to upgrade.
But we also regularly update our demo projects to use the latest versions of the frameworks to ensure that you can use the latest framework versions when you want to.
Angular standalone components
We have added support for Angular standalone components.
Angular dynamic component creation
To optimize the behaviour of Angular 14+ there is an option to distinguish between "properties" and "inputs."
Before assigning properties from Magnolia nodes, the library verifies if they should be set as inputs on the Angular component. This enables the proper use of lifecycle hooks, directives, and other features that rely on inputs.
React Server Components and Next.js App Router (Experimental)
There has been a lot of buzz about "RSC" and rendering some or all components on the server. We have released an experimental version of our react-editor library to support these features. Interested? Give it a try and tell us what you think! (You can just drop a note at the bottom of the Roadmap card to leave feedback, and we will be in touch with you.)
Conclusion
I hope you have learned something that can help you simplify or accelerate or improve the authoring experience of one of your projects. We have also updated the documentation with some useful information about headless vs freemarker projectsheadless vs freemarker projects.
Big thanks to you, the Magnolia community, for reporting bugs and requesting improvements. Super props to people who contributed code for them as well.
And mega props to the Magnolia developer team that implemented all this and takes such care to ensure a great product.