Warning
You're browsing the documentation for an old version of Webiny. Consider upgrading your project to Webiny 5.35.x.

Breaking Changes
anchor

Removed the Headless CMS AWS Lambda Function (#2945 external link)
anchor

Prior to 5.35.0 version of Webiny, all remote GraphQL API HTTP requests were handled by two separate AWS Lambda functions. One function was responsible for serving the Default GraphQL API (accessible via the /graphql endpoint), while the other was responsible for serving the Headless CMS GraphQL API (accessible via the /cms/{type}/{locale} endpoint).

Starting with 5.35.0, all remote GraphQL API HTTP requests are handled by a single AWS Lambda function. In other words, the function is responsible for serving both the Default and Headless CMS GraphQL APIs. Note that the mentioned /graphql and /cms/{type}/{locale} endpoints remain unchanged.

This change will simplify the development and deployment process for the users, and make it much easier to add plugins which interact with the entire system, for example hooking into all the lifecycle hooks Webiny has to offer.

Apart from the usual upgrade guide that’s included with each Webiny release, we’ve also created a separate guide that deals with change in more detail.

Singular and Plural Model API Name (#3111 external link)
anchor

We’ve added the ability to define the singular and plural model API names for the Headless CMS models. Before the version 5.35.0, the API name was always created from the modelId property and for the plural, we used pluralize external link library, which did not create correct plural names for languages other than English.

From now on, models created via the Admin UI will always need to have singular and plural API name defined, but the models created via the code will have the singular and plural API name only if they’re public (exposed via the GraphQL API).

Singular and Plural API NameSingular and Plural API Name
(click to enlarge)
Automated migration
For the singular and plural model API name functionality, we've added an automated migration which will run upon the first project deploy. The migration updates all the models across all the tenants and locales.
If you’re defining content models via code, you can now define the singular and plural API name for the model. If you don’t define the singular and plural API name, the API name will be created from the modelId property and for the plural, we’ll use pluralize external link library.

List File Tags (#3227 external link)
anchor

There was a bug when listing file tags in the DynamoDB + Elasticsearch deployments, where not all tags were returned.

Also, we have upgraded the File Manager listTags GraphQL query to use our standard data, error envelope, and return the tag value and the count value, which represents the number of files that have the tag assigned.

The query now looks like this:

query ListTags {
  fileManager {
    listTags {
      data {
        tag
        count
      }
      error {
        code
        message
        data
      }
    }
  }
}
Programmatic usage

If you are using the listTags GraphQL query directly, you will need to update your code to use the new data, error envelope, as well as the tag and count fields.

createFile Mutation Requires a File Id
anchor

With the Support File Aliases feature, file ID is now mandatory when calling createFile GraphQL mutation. If you’ve never used this mutation programmatically, you can ignore this change. But if you have custom scripts interacting with the File Manager, make sure you update them to include all the data returned from getPresignedPostPayload query, if that’s not already the case.

Changed the Location of FileManagerFileTypePlugin Plugin
anchor

File Manager supports customization of file types by means of FileManagerFileTypePlugin plugin. This class is now exported from the @webiny/app-file-manager. If you’ve implemented custom file type renderers, make sure you update your import statements.

Theme Object Changes
anchor

With this release, we’ve made a change in the data structure of the theme object’s styled.typography object. More on this in the Improved Theme’s styled.typography Object section below.

Default Form Layout Replaced
anchor

Because of all of the theme object-related changes, and also new improvements that have been introduced to the Form Builder application, note that, during upgrade, your default form layout will be backed up and completely replaced with the latest version of the layout. This means that if you have made any customizations to the default form layout, you will need to manually re-apply them to the new layout.

Headless CMS
anchor

Headless CMS GraphQL Schema Plugin (#2945 external link)
anchor

As a part of the Removing the Headless CMS AWS Lambda Function task, there is a new GraphQL Schema plugin which is responsible for the Headless CMS GraphQL schema.

If you were using the GraphQLSchemaPlugin to define your custom schema for the Headless CMS, please replace it with the CmsGraphQLSchemaPlugin.

To learn more, please check out the Removing the Headless CMS Lambda Function article.

Detailed (Advanced) Admin UI Reference Field (#2969 external link)
anchor

We added a new reference field renderer, called Detailed view with modal search. The Detailed renderer is now a default renderer for all the new reference fields, but users can switch to the old one whenever they want to - or from the old one to the new one.

Model Field Appearance TabModel Field Appearance Tab
(click to enlarge)
List of referenced ItemsList of referenced Items
(click to enlarge)
Modal Search of ReferencesModal Search of References
(click to enlarge)
Multiple Model Reference FieldMultiple Model Reference Field
(click to enlarge)
Multiple Model Reference Field Model Choice DropdownMultiple Model Reference Field Model Choice Dropdown
(click to enlarge)

Default Model Fields (#2977 external link #2978 external link)
anchor

We added the ability create a new model with the default fields defined. Default fields are:

  • Title (title) - text field
  • Description (description) - long text
  • Image (image) - file field with images only

By the default, the checkbox defining the default fields creation is checked, but users can uncheck it if they do not want to create the default fields.

Model With Default Fields CheckboxModel With Default Fields Checkbox
(click to enlarge)

Model Icon (#3142 external link)
anchor

We’ve introduced the ability to add an icon when creating or editing a content model. Within the Admin app, an icon picker will be shown when creating or editing content models. For models defined via code, users will need to type in the icon pack identifier and the icon identifier, in form of packId/iconId. For example, a newspaper icon is fas/newspaper.

We have a few icon packs by default: @fortawesome/free-brands-svg-icons (fab), @fortawesome/free-solid-svg-icons (fas) and @fortawesome/free-regular-svg-icons (far).

Disable Dynamic Zone in the Object Field (#3160 external link)
anchor

We disabled the possibility to add the Dynamic Zone field into the Object field. Unfortunately, we were forced to do this for the moment, as we need to implement structural changes in the Headless CMS for this to work properly. This is something we’ll enable in the future, but for the time being, to prevent unexpected situations and problems with the models, you will only be able to use the dynamic zone field as a top-level model field.

GraphQL Schema Types CmsCreatedBy and CmsOwnedBy Replaced With CmsIdentity (#2969 external link)
anchor

As part of the advanced reference field PR, we removed the GraphQL types CmsCreatedBy and CmsOwnedBy in favor of the CmsIdentity type, because they represented the same data.

GraphQL Schema Cache (#3201 external link)
anchor

When the user project did not contain any models in the database (created via the UI), GraphQL Schema cache did not work properly as the generated cache key was faulty. We now generate a correct key, which is used to cache the GraphQL Schema until the next model change, or next deployment of the code.

Code Content Model Without Validation (#3187 external link)
anchor

The projects, which have a lot of the CMS Models created via the code, can get a slow API response due to the validation ran on every request. This PR introduces noValidate property on the CmsModelPlugin external link, for both the API and Private models.

When using the noValidate flag, users will must be extremely careful as we do not check anything they set in that code model.

Benchmark Measurement Points (#3185 external link)
anchor

After adding the Benchmark tool to our system, we added some benchmark points to the Headless CMS.

This allows us, and our users, to figure out bottlenecks during the request, if there are any. Benchmark measurement points cover the GraphQL Schema generation and processing of the request body, at the top level. The measurements cover all our CMS GraphQL Queries and Mutations, as well as the request body processing step.

Page Builder
anchor

Introducing Page Templates (#2963 external link #3086 external link)
anchor

Prior to this release, upon creating pages with the Page Builder application, users would always start with a blank page.

Blank PageBlank Page
(click to enlarge)

For some users, this can be challenging, as it can be hard to get inspiration on how to structure content correctly. In addition to this, websites are often built in a way that pages follow a set of predefined structures. In other words, all product pages look the same, all blog pages look the same, and similar.

In order to tackle this problem, we are introducing a brand new feature called Page Templates!

Via the dedicated templates editor, users can now create page templates that can be used to create new pages.

Templates EditorTemplates Editor
(click to enlarge)

In a nutshell, the idea is that a page template behaves similarly to a block. A user picks a template, that is inserted into the page editor. A user can only populate variables that the template exposes, or the user can “unlink” the template, which allows them to rearrange elements, add new elements and remove existing elements.

We’re excited about this new feature, and we hope you’ll find it useful as well! Start creating your own page templates today and let us know what you think! We’d love to hear your feedback!

Introducing a Brand New Text Editor (#3147 external link)
anchor

With this release, we’re introducing a brand new text editor that will make it even easier to create content-rich pages, blocks, and templates!

Introducing A Brand New Text EditorIntroducing A Brand New Text Editor
(click to enlarge)

The new text editor is based on the Lexical external link framework, and it’s a complete rewrite of the old editor. In a nutshell, it provides better and more familiar editing experience, and it’s also much more extensible.

In terms of backwards compatibility, we’ve made sure that texts created with the old editor continues to work as usual (the old editor will still be used). Only the new texts will be using the new editor.

We hope you’ll enjoy using the new editor! This is the first release of the new editor, and we’re still working on adding new features and improving the overall experience. We have a lot of exciting things planned for the future, so stay tuned!

Introducing Advanced Content Organization for Page Builder
anchor

The Advanced Content Organization (ACO) for Page Builder is a new feature that provides users with the ability to organize content in an effective, easy-to-manage way. The ACO allows users to add pages in separate folders and rearrange content as needed, making it easier to find what they are looking for.

Advanced Content Organization for Page Builder OverviewAdvanced Content Organization for Page Builder Overview
(click to enlarge)

With the new Page Builder pages list users can:

  1. Create and update a multi-level folder structure.
  2. Sort both folders and pages based on “Name” and “Last Modified Date”. This feature makes it easier for users to find specific pages and folders quickly.
  3. Move a page across the hierarchy tree, and it has no impact on the page URL. The two have been decoupled to ensure users have the flexibility they need without having a negative impact on SEO if they decide to restructure their folder/page organization.

In future releases, we are planning to expose public APIs to allow developers to customize the table view, so they can include, modify or remove columns.

Multiple UI Improvements
anchor

Webiny’s Page Builder application has been improved with a new batch of UI improvements.

Exporting Blocks From Current Category (#3109 external link)
anchor

For starters, upon exporting blocks, users can now choose whether they want to only export blocks that belong to the currently selected category of blocks.

Exporting Blocks From Current CategoryExporting Blocks From Current Category
(click to enlarge)

Improved Searching of Blocks (#2968 external link)
anchor

From now on, typing into the SEARCH BLOCKS search field will perform a search across all block categories, where the UI will respond in the following way.

In the list of block categories (left side), it will filter out categories that don’t contain at least one block whose name is matched by the search query. Once a category is clicked, in the list of blocks (right side), only matched blocks will be listed.

Improved Searching of BlocksImproved Searching of Blocks
(click to enlarge)

Improved Sorting of Block Categories (#3099 external link)
anchor

Prior to this release, across different screens within the Admin application, we’ve had different default sorting applied when listing block categories.

For consistency sakes, by default, every list of block categories across different screens within the Admin application will now be sorted alphabetically. User can then apply a different sort, if need be.

Multiple Smaller Blocks-Related UI Improvements (#3106 external link)
anchor

The following are some smaller, but still useful, blocks-related UI improvements we’ve made.

Edit Block Button

In the page editor, once a block has been selected on the page canvas, in the right sidebar, the newly added Edit button enables users to quickly open the block in the block editor and make necessary changes to it.

Edit Block ButtonEdit Block Button
(click to enlarge)
Refresh Block Button

With the Edit button, we’ve also introduced the Refresh button. As the name suggests, once clicked, the selected block will be refreshed, reflecting changes that may have been done to the block by the user potentially in a separate browser tab, or by other user.

Refresh Block ButtonRefresh Block Button
(click to enlarge)
Block Name Displayed In the Page Editor

When a block is selected on the page canvas, the name of the block will be displayed in the top-right corner, making it easier for users to identify blocks on the page.

Block Name Displayed In the Page EditorBlock Name Displayed In the Page Editor
(click to enlarge)
Refresh List of Blocks Button
Refresh List of Blocks ButtonRefresh List of Blocks Button
(click to enlarge)

Previewing Pages From Revisions List Now Works Correctly (#3103 external link)
anchor

In the page revisions lists, clicking on the Preview link would in certain cases incorrectly redirect users to the public website, instead of page’s preview URL.

Previewing Pages From Revisions List Now Works CorrectlyPreviewing Pages From Revisions List Now Works Correctly
(click to enlarge)

This has now been taken care of. Clicking on the link will correctly redirect the user to page’s preview URL.

Fixed Highlighting of Active Page Elements in Page Editor (#3152 external link)
anchor

In the page editor, when clicking on some page elements like Image and Form, orange borders that surround the element would not be rendered correctly.

Fixed Highlighting Of Active Page Elements In Page EditorFixed Highlighting Of Active Page Elements In Page Editor
(click to enlarge)

This has now been addressed. The orange borders should be rendered correctly for all page elements.

Trimming of Trailing Slash in Page Path (#3153 external link)
anchor

In the page editor, in page’s general settings, providing a page path that ends with a forward slash would break background page rendering which happens once the page has been published.

Trimming of Trailing Slash In Page PathTrimming of Trailing Slash In Page Path
(click to enlarge)

From now on, trailing slashes in page path will be removed, ensuring the page gets rendered correctly once published.

Using SEO Title Instead of General Settings Title (#3155 external link)
anchor

From now on, the title specified in the SEO settings section will be used as the title for published pages (title set via the <title> external link HTML tag).

Using SEO Title Instead Of General Settings TitleUsing SEO Title Instead Of General Settings Title
(click to enlarge)

Previously, the title specified via the General settings would be used instead, which, often, we’ve seen it’s not something users would expect.

The title specified in the General settings section will still be used as the page title if one wasn't specified in the SEO settings section.

Improved Grid and Cell Page Elements (#3012 external link)
anchor

Grid page element now provides users with a couple of new features in page element settings.

For starters, users can now choose the number of rows for the grid, enabling them to quickly have multiple rows of columns, and not just one.

Grids With Multiple RowsGrids With Multiple Rows
(click to enlarge)

And with the new Column gap and Row gap settings, users can add spacing between grids and cells:

Column and Row gap settingsColumn and Row gap settings
(click to enlarge)

Furthermore, grid cells can now be vertically expanded and take the full height of the parent grid via the new Column height setting.

Grid Cells Vertically ExpandedGrid Cells Vertically Expanded
(click to enlarge)

Finally, users can now apply vertical centering of content placed in grid cells.

Vertical Centering Grid Cells Vertically ExpandedVertical Centering Grid Cells Vertically Expanded
(click to enlarge)

Improved Theme's styled.typography Object (#3147 external link)
anchor

Prior to this release, within the theme object, the styles.typography property referenced an object where keys represented the typography variant (heading1, heading2, etc.), and values were objects representing the actual typography styles.

From now on, the styles.typography property references an object where keys represent the typography type (heading, paragraph, etc.), and values are arrays of objects, where each object represents a specific typography variant. Each typography variant is an object that consists of four properties: id, name, tag, and styles. For example:

apps/theme/theme.ts
{
  // ...
  styles: {
    typography: {
      heading: [
        {
          id: "heading1",
          name: "Heading 1",
          tag: "h1",
          styles: {
            // ...
          }
        },
        {
          id: "heading2",
          name: "Heading 2",
          tag: "h2",
          styles: {
            // ...
          }
        },
        // ...
      ],
      paragraph: [
        {
          id: "paragraph1",
          name: "Paragraph 1",
          tag: "p",
          styles: {
            // ...
          }
        },
        {
          id: "paragraph2",
          name: "Paragraph 2",
          tag: "p",
          styles: {
            // ...
          }
        },
        // ...
      ],
      // ...
    }
  }
}
For more information, please refer to our updated Theming article. Furthermore, for more information on migrating your existing theme to the new structure, please refer to our Upgrade From 5.34.x to 5.35.0 article.
Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

Theme Object Now Available in Emotion Styled Components (#3141 external link)
anchor

Prior to this release, if users wanted to use Emotion styled components external link with their custom page elements external link and needed to access the theme external link, they were unable to do it as documented in Emotion’s Theming external link documentation article, which is via the React context external link.

With this release, the theme will internally be loaded into Emotion’s ThemeProvider, meaning it will be available in your custom Emotion styled components.

The following is an example of an Emotion styled component that uses the theme object:

export const HeroSectionWithTheme = styled.div(({ theme }) => ({
  lineHeight: "125%",
  backgroundColor: theme.styles.colors.color1,
  backgroundRepeat: "no-repeat"
}));
Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

Custom Responsive Emotion Styled Components Are Now Rendered Correctly in the Page Editor (#3141 external link)
anchor

Prior to this release, if users wanted to use Emotion styled components external link with their custom page elements external link, they would be unable to see them adapt to different screen sizes in the page editor, while building their pages. Essentially, different CSS rules defined via media queries external link would work on the public website, but not in the page editor.

With this release, your custom responsive Emotion styled components should be rendered the same both on the public website and in the page editor.

Ensuring responsive design works on both public website and in the page editor was achieved via the @container CSS at-rule external link. Essentially, the page canvas in the page editor is now a container, and, while in the page editor, breakpoints and their @media queries defined in the theme external link get transformed into @container pb-page-canvas rules.

More information on this can be found in the new Theming article.
Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

Introduced mq Utility Function for Easier Styling (#3141 external link)
anchor

One of the tools that is recommended in Emotion external link library’s documentation portal is Facepaint external link. The library enables the developer to easily define CSS rules for multiple pre-defined breakpoints, for example:

import { css } from "emotion";
import facepaint from "facepaint";

const mq = facepaint([
  "@media(min-width: 420px)",
  "@media(min-width: 920px)",
  "@media(min-width: 1120px)"
]);

const myClassName = css(
  mq({
    color: ["red", "green", "blue", "darkorchid"]
  })
);

With this release, we’ve decided to include this library in the @webiny/app-page-builder-elements external link package, enabling users to immediately use it, without the need to install it first. Furthermore, by importing the mq utility function, users can immediately start writing their per-breakpoint styles, because the function is already configured to follow the breakpoints defined in the theme external link. For example:

import React from "react";
import { mq } from "@webiny/app-page-builder-elements";
import styled from "@emotion/styled";

// Basic usage.
export const HeroSection = styled("div")(() =>
  mq({ color: ["red", "green", "blue", "gray", "white"] })
);

// With theme being accessed via the `theme` argument:
export const HeroSectionWithTheme = styled("div")(
  {
    lineHeight: "125%",
    backgroundColor: "#fff",
    backgroundRepeat: "no-repeat"
  },
  ({ theme }) =>
    mq({
      color: [
        "red",
        theme.styles.colors.color1,
        theme.styles.colors.color2,
        theme.styles.colors.color3,
        theme.styles.colors.color4
      ]
    })
);
More information on this can be found in the new Theming article.
Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

Input Validation With Zod Library (#3167 external link) (#3194 external link)
anchor

We replaced the Commodo validation (our custom package) with the Zod library external link. The validation is now a lot more strict and this is a preparation for the ability for users to customize the validation - not available yet.

Title and Path Maximum Length (#3188 external link)
anchor

The Page Builder title and path properties are now set to be maximum of 500 characters.

Website - Clicking on Links No Longer Does a Full Page Refresh (#3215 external link)
anchor

Prior to this release, clicking on links rendered by Pages List, Button, and Image page elements would cause a full page refresh, making the UX for the website visitor not as good as it should be.

This has now been addressed. Clicking on links rendered by these page elements will cause the following page to be rendered immediately, without a page refresh happening.

Website - Added Missing Tenant Error Message (#3202 external link)
anchor

Prior to this release, if a user would open their website application in local development and their Webiny project had multi-tenancy feature enabled, then they would just see a blank screen in case the tenant ID hasn’t been set previously. No errors would be shown in the browser console too.

Additional point of pain would be the fact that setting the tenant ID is also something that was not clear and, in almost all cases, would left users further confused.

To address this, we’ve added better error reporting and ensured users are aware what are the next steps. The following is the error message that will be shown to users in their browser:

Website - Added Missing Tenant Error MessageWebsite - Added Missing Tenant Error Message
(click to enlarge)

Page Editor - Addressed Canvas Width Indicator Issue (#3216 external link)
anchor

The canvas width indicator displays the width of the canvas, which changes depending on the selected breakpoint (desktop, tablet, mobile-landscape, mobile-portrait). Due to an internal bug, the indicator would always report 100px as the width, which was incorrect.

This has now been addressed, so the actual canvas width should now be displayed correctly.

Page Editor - Canvas Width Indicator Now Works CorrectlyPage Editor - Canvas Width Indicator Now Works Correctly
(click to enlarge)

Form Builder
anchor

Introduced E-Mail Triggers (#2957 external link)
anchor

E-mail - Submission NotificationE-mail - Submission Notification
(click to enlarge)
E-mail - Thank You E-mailE-mail - Thank You E-mail
(click to enlarge)

Under the Form Builder triggers you’ll now find two new options. The “E-mail - Submission Notification” trigger sends an email every time a form submission is received. This way it’s much easier to stay updated when someone submits one of your forms.

The “E-mail - Thank You E-mail” trigger sends an email to the user who submitted the form. Inside the email content, you can use the {fields.FIELD_NAME} variable to display the form submission data, adding personalization to your emails.

Added the Ability to Import/export Forms (#3077 external link)
anchor

Form Builder - Export formForm Builder - Export form
(click to enlarge)

We’ve added the ability to export selected forms from the system and easily import them into another system. This way, you can easily move your forms from one environment to another.

Improved Export of Submissions (#3093 external link #2965 external link)
anchor

We made several updates to the way form submissions are exported. Firstly, the exported CSV file will now contain the exact date and time (UTC) when the submission was created. Secondly, the export format has been improved to make it easier to read. Fields like the checkbox and radio button that previously contained the field value instead of the label, making it hard to read, have been fixed.

Introduced Copy Form Submission to Clipboard (#2952 external link)
anchor

Form Builder - Copy submissionForm Builder - Copy submission
(click to enlarge)

When you preview the submission details in the modal dialog you’ll notice two new buttons in the top right corner. The “Copy as JSON” and “Copy as CSV” buttons will copy the submission data to your clipboard, so you can easily paste it into another application.

Ability to Have "Other" Option (#3031 external link)
anchor

Form Builder - Other settingsForm Builder - Other settings
(click to enlarge)
Form Builder - Other previewForm Builder - Other preview
(click to enlarge)

We’ve added the ability to have an “Other” option in the radio button and checkbox fields. This way, you can easily allow users to add a custom value to the field.

Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

Multiple Improvements on the Default Form Layout (#3009 external link #2950 external link #2964 external link)
anchor

We’ve made several improvements to the default form layout. The most notable ones are:

Form Builder - Required toggleForm Builder - Required toggle
(click to enlarge)

You can now view and toggle the required indicator on and off directly from the form layout editor.

Form Builder - Required indicatorForm Builder - Required indicator
(click to enlarge)

Previously the required fields didn’t have any indicator on them to show that they are required. We’ve added a red asterisk to the field label to make it clear that the field is required.

Form Builder - Help textForm Builder - Help text
(click to enlarge)

The position of the field help text has now been moved under the title to make it easier to read.

Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

Added Basic Form Field ID Validation (#3017 external link)
anchor

Form Builder - Field ID ValidatorForm Builder - Field ID Validator
(click to enlarge)

We’ve added a basic validation to the form field ID. Previously, you could enter any value as the field ID, which could cause different issues in the system. Now, you can only enter letters, numbers, and underscores.

Security
anchor

Cognito Custom ID Attribute (#3090 external link)
anchor

Cognito User Pools will now have a new custom attribute custom:id containing a unique identity ID generated by Webiny. This will allow developers to export users from Cognito User Pools and maintain the identity IDs when importing those users into new User Pools.

By default, Cognito generates a sub attribute, which we used as a unique identifier for the user. That, however, poses a problem with backups and restoration, since AWS generates new values for the sub attribute upon importing the user into the user pool. To abstract Webiny away from this problem, from now on, we will generate our own unique identifier, and store it as a custom:id attribute, and use that to map Cognito identities to Webiny.

This change is backwards compatible; all existing identities will use the sub attribute, and the new ones will also have the new custom:id attribute generated.

Cognito Custom Authorization Logic (#3054 external link)
anchor

You can now reuse our default Cognito security package to implement custom authentication and authorization logic, without using the low level API. This gives you the ability to create protected user areas on your websites, etc.

See a full working example in the following repo: https://github.com/webiny/webiny-examples/blob/master/gated-content/packages/api/src/createWebsiteSecurity.ts external link

Security withoutAuthorization Method (#3176 external link)
anchor

There is now a withoutAuthorization method on the context.security object. It is intended to replace the context.security.disableAuthorization() and context.security.enableAuthorization() methods.

The problem with these legacy methods is that they explicitly enable/disable authorization without any checks, or execution context awareness. In some situations, this caused authorization to be enabled when it shouldn’t, and code would start throwing authorization errors.

The new security.withoutAuthorization() method keeps track of the current state of authorization, and will not re-enable authorization if it was already disabled when the execution cycle started.

The following code demonstrates how you can use the new method, and have full TS support:

const result = await context.security.withoutAuthorization(async () => {
  const params = {
    myParam: 1,
    anotherParam: 2
  };
  return userCustomCodeCallWhichNeedsToHaveAuthorizationDisabled(params);
});

Tenant Tags (#3136 external link)
anchor

We’ve introduced a new tags field on tenants, to allow various use-cases to be implemented programmatically. Tags can be very useful when filtering tenants, or applying conditional logic, like data propagation, etc.

Tenant TagsTenant Tags
(click to enlarge)

File Manager
anchor

Support File Aliases (#3096 external link)
anchor

File Manager now supports file aliases. This means that you can specify one or more aliases on each file, and our File Manager will be able to route the request to the actual file in our S3 bucket. This is useful when migrating files from other systems, when you need to preserve the URLs in your existing content. Internally, files are still stored to the S3 bucket following Webiny path structure.

File AliasesFile Aliases
(click to enlarge)

With this, we’ve also improved the way we store files into the bucket. We now have a unique ID for every file, which is used as a folder name, and all file related content (resized images, transformed images, etc.) is stored within that folder. This simplifies file management, cleanup, and gives us a home folder for every file, where we can store additional things related to the file.

Backwards Compatible
This change is backwards-compatible. Existing systems will continue to work like they did previously, and the new folder structure will only be applied to the new files created after the 5.35.0 upgrade.

Lifecycle Events (#3120 external link)
anchor

File Manager context now exposes lifecycle events, as any other Webiny app. You can now programmatically hook into file’s life cycle, and do various things with single files, as well as with batches of files.

See an example of some events exposed:

new ContextPlugin<FileManagerContext>(async context => {
  context.fileManager.onFileBeforeCreate.subscribe(async params => {
    console.log("I'm about to create a file!");
  });
  context.fileManager.onFileAfterCreate.subscribe(async params => {
    console.log("I've created a file!");
  });
});

File DB Storage Improvements (#3083 external link)
anchor

Some users are pushing Webiny to its limits with the amount of files they’re uploading into the system (counted in millions). For this reason, we’ve introduced some improvements on the primary key and global secondary indexes of file records in the DynamoDB table, to eliminate the possibility of having hot partitions.

This comes with an automated migration which will be executed upon the deployment of the upgraded project.

Migration Execution Time

Please note that, depending on the amount of files in your system, this migration can take some time. Some internal tests show ~30 minutes for 4 million files, in a DDB-ES project setup. The migration is not touching the files in the bucket, but is creating new DB records with the new primary key and GSIs, to optimize data storage and access.

Development
anchor

Data Migration Lambda Function (#3079 external link, #3150 external link)
anchor

Applying data migrations is always challenging. With this release, we’re introducing an automated migration runner, which runs on each API deployment, checks if any migrations need to be executed, and if so, runs them in a safe, resumable manner. It takes into account project versions, your current state of the database (and Elasticsearch), creates checkpoints in the process, and allows you migration to run for as long as necessary, even hours.

The way migrations are written, allows developers to revert their code to the previous working version, and redeploy, in case something goes wrong with the upgrade. Data in the database is always upgraded in a way that allows rollbacks.

Can I see the migration source code?

All migrations can be found in the @webiny/migrations external link package. The package contains the actual migrations, as well as tests for each individual migration, so you can inspect them, and see the exact modifications we’re doing on the data.

Introduced Application Name-Based Environment Variable Naming (#3095 external link)
anchor

With this release, we’re simplifying the way environment variables are defined by users.

We’re introducing the following environment variable prefixes, where each prefix designates into which project application the variable will get assigned:

# Variables with this prefix will get assigned into all AWS Lambda
# functions deployed as part of the API project application.
WEBINY_API_

# Variables with this prefix will get assigned into the Admin React application.
WEBINY_ADMIN_

# Variables with this prefix will get assigned into the Website React application.
WEBINY_WEBSITE_

Note that this new feature is backwards compatible. All previously defined environment variables in users’ projects will still work as usual.

Emotion 11 (#3138 external link)
anchor

With this release, we are upgrading Emotion external link library to version 11.

This upgrade enables Webiny users to use all of the latest and greatest features the library offers.

For Webiny itself, the new version enabled us to provide the theme object upon creating custom Emotion styled components.

Note that the migration script included with this release will ensure the library is upgraded to the new version. Users do not need to upgrade the library manually.

Note that in order to receive these changes, your project must be using the latest Page Builder page rendering engine, introduced with Webiny 5.34.0.

New Frontend Utility Functions (#3126 external link)
anchor

A couple of new useful frontend development-related utility functions have been introduced in this release.

import {
  getApiUrl,
  getGqlApiUrl,
  getHeadlessCmsGqlApiUrl,
  getLocaleCode,
  getPrerenderId,
  getTenantId,
  isLocalhost,
  isPrerendering
} from "@webiny/app-website"; // Or "@webiny/app-admin".

// Returns URL of Webiny's backend API.
getApiUrl(); // https://xyz.cloudfront.net

// Returns URL of Webiny's backend GraphQL API.
getGqlApiUrl(); // https://xyz.cloudfront.net/graphql

// Returns URLs of Webiny's backend Headless CMS GraphQL API.
getHeadlessCmsGqlApiUrl(); // { preview: "...", manage: "...", read: "..."}

// Returns locale used on the page.
getLocaleCode(); // en-US

// Returns current prerendering process' ID.
getPrerenderId(); // abc123xyz

// Returns current tenant.
getTenantId(); // root

// Returns `true` if the application is run on localhost.
isLocalhost(); // true

// Returns true if the page is being prerendered.
isPrerendering(); // true

Except for the prerendering-related utility functions, these can be used within both Admin and Website applications.

API Benchmark (#3183 external link)
anchor

We added the benchmark tool to the main context object. It is initialized by default, but it is not enabled.

To find out more about our benchmark tool and how to enable it in your project, please read this article.