Best practices
A best practice is a way of working that consistently yields better results. Best practices save time and effort and result in more maintainable projects.
Administration
Disk space
We recommend that you allocate at least 50GB of disk space for an author instance and 25GB for a public instance.
See Disk space
Apps
Add a Container instance in your ContentConnector
Make the Container instance available in your ContentConnector. This makes it easier to implement item and itemId related methods. This works only if you have only one Container per subapp. If you need more Containers you must decouple the Container and the ContentConnector.
Displaying content stored in apps
See Search
Define as a component anything that is likely to change
Defining something as a component allows other developers to quickly change the implementation. For this reason, you should define anything that is likely to be changed or customized later as a component. For example, define your apps and subapps as components. Views are also common customization points so define the views returned by subapps as components. Any components you define are available for injection. This is also true for components further up the hierarchy in parent components.
Fields
Forms
Checking for null values
See Field validators
Internal linking
Implementing internal links in Magnolia involves deciding how to resolve and handle links between nodes in the JCR repository.
Each approach, JcrNodeToPathConverter
, JcrNodeToIdConverter
, or relying on the Magnolia core templating functions, offers unique advantages and trade offs depending on project requirements.
See Internal linking best practices for more details.
HTTP headers and security best practices
In this subsection, we provide some ideas how you can improve security through select HTTP headers.
Content Security Policy (CSP) header
Content Security Policy governs what a web browser (or a user agent, in general) is allowed to load as part of a page. Setting a CSP header allows the creator of a page to control what other resources might be loaded by the underlying HTML or JavaScript code. This is a powerful way to mitigate many Cross-site scripting (XSS) attacks.
You should list, as part of the header value, the origin and all the endpoints required for the page to function. However, if you allow any endpoint that is not within your control, you are opening a hole through which an attack might be staged.
If necessary, we recommend you customize the header to define your own whitelist.
-
Create a new filter manually in the Configuration app and add the
Content-Security-Policy
property under it. -
An example configuration could look similar to the one below. The path
server/filters/HeaderFilterOne
is only a suggestion. When adding CSP headers, you only need to place the header values into theContent-Security-Policy
property.📁 server
📁 filters
📁 HeaderFilterOne
⬩ class
info.magnolia.cms.filters.AddHeadersFilter
⬩ enabled
true
📁 headers
⬩ Content-Security-Policy
default-src `self' `unsafe-inline' `unsafe-eval' https://ga-dev-tools.appspot.com https://apis.google.com https://www.google.com https://content.googleapis.com https://ajax.googleapis.com ; img-src `self' data:;
The Vaadin framework performs the CSP check explicitly instead of relying on browser to do so as part of policy execution. You can see official Vaadin statement here. |
JSON requests are processed when Content-Type is text/plain?
This does not present a security vulnerability in Vaadin.
Vaadin doesn’t enforce Content-Type: application/json
because it doesn’t rely on it for security.
Requests with an incorrect Content-Type
fail if the content is malformed.
This ensures compatibility with technologies like Portlets.
For more details, see Advanced Vaadin Topics: Content Type Incorrectly Stated.
Vaadin secures requests using CSRF tokens, not Content-Type
validation.
See also
Strict-Transport-Security
(STS) header
The STS header informs the browser that a page should only be accessed over the HTTPS protocol. The browser will use this knowledge and set all future requests for the same domain to go through HTTPS automatically, thus preventing the extra round trip that might be required otherwise.
Using HTTPS instead of HTTP enables traffic encryption between the page and the client, preventing anyone from intercepting the communication. Using this header is considered more secure than using the 301 redirect on the server when an attempt for the over-the-HTTP access is made.
See also:
X-Content-Type-Options
(XCTO) header
XCTO is a marker header that tells the client that the media types (MIME types) advertized as part of the Content-Type headers should be strictly followed and not changed. This helps avoid MIME Type Sniffing.
See also:
X-Frame-Options
(XFO) header
Setting the XFO header tells the browser that the given page is not allowed to be embedded in another page. This header setting helps mitigate stealing content, clickjacking (UI redress attack) or allowing malicious sites to pose as the regular ones and fool the users to not check the URLs closely but think instead that they are on a safe page when they are actually not.
See also:
Language
Provide a message bundle
With message bundles a translator can work with a plain text file and doesn’t need to touch the code.
Modules
Create your own webapp
To create a custom Magnolia webapp, always start with a preconfigured Magnolia webapp.
Use the properties
section to define versions. The section may the serve as a central part for organizing all versions required by your project.
Create separate modules for templates, content and resources
When you are creating a website project, you should have one module for templates, another module for content, a third for a theme and so on.
See Modules
Multisite
Author domain
In a multisite setup with one Magnolia installation, you assign multiple domains to the public instance. However, it is sufficient and recommended to have only one domain pointing to your author instance. The domain of the author instance is different from the domains of the public instance.
Site definition name and handle prefix
Use different values for the site-definition-name
and the name of the mapped node (handlePrefix
).
Turn off domains and mappings inheritance
When extending site definitions, turn off inheritance for mapping
and domains
by using @extends=override
.
Personalization
Create traits that have a clear set of allowed values
Every trait has inherent allowed values. For example, locations are countries, ages are numbers, and genders are either male or female. Create traits that have a clear set of allowed values. Traits that have vague values are difficult to detect and assign. Also, make sure the trait applies to the majority of your audience. "New vs. returning visitor" is a good trait because the values are easy to detect and it applies to every visitor.
See Personalization
Create a segment only when you know your audience well
Create a segment only when you know your audience well and have targeted at least one successful campaign to them using local rules. Visitors who share a combination of traits are good candidates for segmentation if they respond well to personalization. For example, add visitors who previously bought a product to a "Previous buyers" segment and offer them a discount as a reward for return business. Segmentation helps you repeat successful personalization experiments. Start with local rules, move to segmentation later.
See Personalization
Resources
Use a dedicated CSS pre-processor
See Resources
REST
Delivery API response time and performance
Following these best practices help improve the response times and performance for the Delivery API.
-
Minimize references.
Using reference resolvers can impact the response times significantly. If the data contains a lot of referenced properties, the request processing times may be considerably longer.
-
Minimize asset renditions.
Each asset rendition config added to the endpoint definition increases the request processing overhead regardless of whether the asset renditions do or do not exist.
-
Minimize response size.
A large response can take longer to generate and return.
-
Minimize the value of the
depth
property.Extra but unnecessary depths configured may have a major impact on response times. Even just one extra depth level can have an adverse effect on the responsiveness of the endpoint.
For example, setting
depth
to4
may take five seconds to process, whereasdepth: 5
could easily increase it to twenty seconds.When needing to retrieve a hierarchical collection of nodes such as to build a sitemap, a navigation, or to represent the hierarchy of content in a content app, consider retrieving just one or two depths of content at once, and then making further requests as necessary.
-
Adjust the caching configuration.
Using cache can boost the performance of your endpoint. The default cache response threshold value is
500
. This means that responses for data larger than 500 kilobytes are not cached.If your endpoint will be handling much larger chunks of data, consider modifying the
cacheResponseThreshold
property accordingly. For more details, see cache threshold.
Security
Create an app group for your own apps
Create a new app group for your own apps, especially if you have multiple apps. This approach is better than placing your apps in the native Magnolia groups. A dedicated group gives your organization’s apps an identity and makes them instantly recognizable.
See App permissions
Provision apps only to users who need them
Provision apps only to users who actually need them. This ensures that the app launcher stays uncluttered and users find apps quickly.
See App permissions
LDAP groups
When you store groups in LDAP, create one matching group per role in Magnolia. Assign roles to the group in Magnolia in order to grant users the permissions they need. This minimizes the number of groups you need to create in Magnolia.
See Group resolving
Separate message bundles
Create separate message bundles for user interface labels and template labels. Don’t store these two groups of text in the same properties files or message bundles. They are aimed at different audiences and have different localization requirements.
Example: Message files in the Travel Demo
-
module-travel-demo-backend_en.properties
(user interface labels) -
module-travel-demo-frontend_en.properties
(template labels)
Workflow and tasks
Don’t use tasks for non-human workflows
Do not use tasks if you don’t have any human activity in your workflow. They are great for humans but unnecessary for operations that only involve the system itself.
See Tasks
Configure your content staging instance as a public instance
Configure your content staging instance as a public instance so that users cannot edit pages on it. The Pages app does not display the green edit bars on public instances. You typically don’t want reviewers to change content on the staging instance. While reviewers may need permission to log into the AdminCentral to review functionality such as new apps, they should not edit pages. The staging instance is intended for testing and approving only. If something is not correct, fix it on the author instance and publish again to staging for another test.
See Content staging