Table of Contents

Headless

How to approach headless in DynamicWeb 10.

Headless CMS and eCommerce

A headless architecture allows for more efficient development and deployment, greater flexibility in terms of content delivery, and enables companies to be more agile, allowing them to quickly adapt to changes in the market and customer needs.

Headless refers to a type of architecture in which the front-end and back-end of a website or application are decoupled. In a traditional architecture, the front-end (or “head”) is tightly integrated with the back-end, meaning that changes to one will often require changes to the other, which can be time-consuming and costly. With a headless architecture, the front-end and back-end communicate with each other through web APIs.

Headless in DynamicWeb

All content in DynamicWeb is exposed to the frontend via ViewModels - traditional DynamicWeb implementations are using Razor template to render the markup on the server.

Instead of injecting the ViewModels into a template and render the markup on the server, DynamicWeb also supports a full featured web-api that exposes all the same ViewModels and data in a REST based services.

As an example, let's say we have created and item type called "BlogPost" and create a page using this item type.

The BlogPost item type have these fields:

  • Title
  • Author
  • Image
  • Text
  • Link

Blogpost itemtype

Creating a new page using the blog post item type will allow you to add the content on the page

Blogpost item

The same piece of content can bed rendered in Razor based templates using ViewModels but can also bed fetched using the delivery API.

Rendering a Blogpost page in Razor

A ViewModel instance of a given page is injected into the template and rendered

@inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.PageViewModel>
<div>
    <h1>@Model.Item.GetString("Title")</h1>
    <p>
      Written by @Model.Item.GetString("Author")</p>
    <p>
        @Model.Item.GetString("Text")
    </p>
    <p>
        <img src="@Model.Item.GetFile("Image").Path" />
    </p>
    <p>
        <a href="@Model.Item.GetLink("Link").Url">Read more</a>
    </p>
</div>

Retrieving a Blogpost page using the headless delivery endpoint

The same page is available on the delivery API by requesting the page by its ID

GET https://localhost:6001/dwapi/content/pages/13

The ViewModel is then returned as a json document that can be used to render the blogpost using a JS component.

{
  "id": 13,
  "name": "My blog post",
  "createdDate": "2023-06-14T13:32:34.873",
  "updatedDate": "2023-06-14T13:45:22.1844074+02:00",
  "title": null,
  "description": null,
  "keywords": "",
  "areaID": 1,
  "path": [
    {
      "id": 3,
      "name": "About us"
    },
    {
      "id": 13,
      "name": "My blog post"
    }
  ],
  "languages": [],
  "item": {
    "fields": [
      {
        "name": "Title",
        "systemName": "Title",
        "value": "My blog post"
      },
      {
        "name": "Author",
        "systemName": "Author",
        "value": "Nicolai Pedersen"
      },
      {
        "name": "Image",
        "systemName": "Image",
        "value": [
          {
            "extension": ".png",
            "name": "contentarea.png",
            "path": "/Files/Images/ExampleImages/contentarea.png",
            "focalX": 0,
            "focalPositionFromLeft": 50,
            "focalY": 0,
            "focalPositionFromTop": 50,
            "pathUrlEncoded": "%2FFiles%2FImages%2FExampleImages%2Fcontentarea.png"
          }
        ]
      },
      {
        "name": "Text",
        "systemName": "Text",
        "value": "<h2>Simplify eCommerce</h2>\n<p>DynamicWeb is PIM, eCommerce, Marketing and CMS in one powerful Commerce Suite featuring standard integrations to Microsoft Dynamics ERP.</p>\n<div>\n<p>Create an omnichannel B2B, B2C or D2C commerce experience using a modern&nbsp;<a href=\"https://dynamicweb.com/technology/mach\">MACH based application</a>, enabling you to build, run and scale your business the way you want.</p>\n</div>"
      },
      {
        "name": "Link",
        "systemName": "Link",
        "value": {
          "pageId": 5,
          "paragraphId": 0,
          "url": "/contact",
          "isExternal": false
        }
      }
    ],
    "id": "1",
    "systemName": "BlogPost",
    "pageID": 13,
    "paragraphID": 0,
    "link": "/about-us/my-blog-post"
  },
  "propertyItem": null
}

Development and frameworks

In headless implementations you can use any JS framework and development tool stack you desire.

An example of development stack:

  • Git
  • VS Code
  • Node
  • NPM
  • Webpack/Vite/Esbuild, ESlint etc.

Some of the more popular frameworks for implementing headless are:

  • React
  • Vue
  • Next.js
  • Nuxt.js
  • Angular
  • Flutter - for developing native apps using data from DynamicWeb

Things to consider

In a regular DynamicWeb implementation using server side rendered, you are operating in a stateful context

When implementing in headless you are operating in a stateless context.

The difference is that in the stateful context DynamicWeb will keep track of the context and state of the current visitor. When in the stateless context your JS app needs to keep track of the state of the current visitor.

Examples of state that needs to be handled in the JS app:

  • URLs and History
  • User logins
  • Carts
  • Chosen language
  • Chosen currency
  • Chosen delivery country
  • Impersonation rules

Hosting headless implementations

A headless implementation consists of at least 2 parts.

  • A DynamicWeb installation that holds all the content
  • Your JS app with js files, components, css and static resources

Since the JS app is completely decoupled from DynamicWeb and is consuming data using DynamicWeb as a micro service, it is possible to host the actual app in a location that is not together with DynamicWeb files.

It can be hosted on a CDN like Heroku, Netlify, AWS, Azure and other cloud services. The benefit is that many of these services comes with a CDN making it possible to load the static assets and the app very fast and only get the actual data from DynamicWeb.

The alternative to using a CDN based cloud offering for the JS app, is to upload it into DynamicWeb file system.

Web API

DynamicWeb comes with 2 web-apis.

  • Delivery API - for creating websites and commerce experiences
  • Management API - for complete managing of a DynamicWeb solution

Delivery API

The DynamicWeb delivery API is a read-only REST API for delivering content from DynamicWeb to websites, apps and other external applications.

In a CMS only installation, the delivery API delivers data:

  • Websites
  • Pages
  • Paragraphs
  • Gridrows
  • Navigation & Urls
  • Translations
  • Users

In a Suite installation, delivery API also delivers ecommerce related data:

  • Products, groups and variants
  • Cart
  • Orders (Customer center)
  • Favorites
  • Payments
  • Shipping
  • Currencies
  • Countries
  • Feeds (PIM only)

The delivery API is available on all solutions on the address /dwapi/content/

A Swagger documentation and test UI can be accessed on /dwapi/docs/

The API can be accessed anonymously and will return data that is available for anonymous users. Users can also be authenticated and a JWT token is issued. Endpoints can be accessed using the JWT token as a Authorization bearer token header in the request:

Authorization: Bearer <token>

Read more about the Delivery API

Management API

The Dynamicweb management API is full featured API that can be used to do everything in Dynamicweb that can be done via the UI.

  • Query data
    • I.e. get pages, users, files or any other data model available in the backend
  • Create, update and delete data models
    • I.e. Creating pages, products, users or deleting them
  • Perform commands
    • I.e. building indexes, start tasks, deactivate users, update prices or stock levels etc.

The management API is considered as a 'low-level' API with access to all types of data in DynamicWeb. So using it requires to understand the entire structure in DynamicWeb. I.e. to create a product in a group and give the product a price requires that a product is created, a relation to the group is created and a price is crated in the price matrix. So at least 3 different models and commands are needed.

The API can only be used with a valid API key. Keys are created in the backend of DynamicWeb in settings->developers.

The API key is used as a Authorization bearer token header in the request:

Authorization: Bearer <token>

Read more about the Management API

To top