Functions
What are functions?
Functions are serverless workloads that run on the Contentful infrastructure to provide enhanced flexibility and customization. You can use functions to:
- connect to external systems and enrich the response of requests issued through Contentful’s GraphQL API,
- filter, transform, and handle events coming from Contentful without having to set up your own server, or
- easily add a backend component to your app that can process actions triggered by the frontend, the CMA, or even by other apps.
Function workloads are executed in a sandboxed runtime environment. For more information, see the function limitations section.
Use case: Native external references
The Native external references feature allows you to seamlessly integrate content from external sources directly within your content model. By leveraging existing reference fields in the content model and the App Framework, you can link to third-party systems and pull content directly into Contentful without the need to create a custom frontend app.
Native external references use the standardized ResourceLink object entity to store references in a standard format which is native to the Contentful platform.
Native external references example
Examples showcase full functionality of Native external references.
The function event handler can parse 4 native external reference specific types of events:
- resources.search – retrieval of specific content based on search queries.
- resources.lookup - retrieval of specific content based on URNs (IDs).
- graphql.resourcetype.mapping - retrieval of resource type mappings, which determines what fields map to an external type. Only required for GraphQL API resolution.
- graphql.query - handles requests for resolving external data from GraphQL queries for the third-party API including introspection queries. Only required for GraphQL API resolution.
graphql.resourcetype.mapping and graphql.query handlers are only needed for GraphQL API resolution. CDA resolution requires only resources.search and resources.lookup which allows querying NER data by setting the externalReferences=* query parameter. See CDA documentation.Each field that is configured with functions must map to a schema. We need to know the relation with the field and the corresponding GraphQL type in the function. Therefore, the field mapping response should include a field mapping for each field.
Given the schema below:
Here is the typing for GraphQLResourceTypeMapping:
GraphQLResourceTypeMapping would have the following values for the product field:
To get the schema, we run an introspection query that ends up triggering the graphql.query event. Note that this might happen repeatedly, and not when you install an app.
Use case: Custom external references
At times, you may need to reference content stored outside of Contentful. With [Custom external references][external-references-feature] you can seamlessly integrate your custom code within the delivery context. Some of our marketplace apps, such as Shopify, Commercetools and Cloudinary, already have out-of-the-box support for this feature. For more information, see the Custom external references page.
Custom external references examples
Examples showcase full functionality of Custom external references.
The following diagram displays the function request flow:

The function event handler can parse two different types of events:
- GraphQL field mapping event – the information returned by your function for this event is used to decide which GraphQL type is exposed on the additional
_datafield. - GraphQL query event - your function will receive this event whenever we want to get data for a GraphQL request. This includes introspection queries.
The function event handler can return two different types of responses:
Each field that is configured with functions, must map to a schema. We need to know the relation with the field and the corresponding GraphQL type in the function. Therefore, the field mapping response should include a field mapping for each field.
Given the schema below:
Here is the typing for GraphQLFieldMapping:
GraphQLFieldTypeMapping would have the following values for the product field:
The information coming in the event.fields array in the field mapping event is driven by the annotations that are added to the field once you enable Resolve content on delivery checkbox.
To get the schema, we run an introspection query that ends up triggering the graphql.query event. Note that this might happen repeatedly, and not when you install an app.
Custom external references templates
Templates allow developers to quickly scaffold an app with custom external references functions. These templates provide a starting point with skeleton code — you must add your custom logic to meet your specific use case.
Use case: App Events
Subscribing to App Events unlocks powerful hooks into the content lifecycle, but it requires setting up and hosting a backend app. Using functions with App Events, developers gain access to a fully managed, scalable, and resilient serverless workflow that eliminates the need for custom backend infrastructure.
Functions streamline interaction with App Events, simplifying the process for developers. They can be used to:
- orchestrate intricate workflows across various services.
- perform resolution and hydration of data from external systems.
- implement custom logic to manage event-triggered builds or cache invalidation.
The following App Event functions are supported:
- Filter functions that run before any other processing, and are used to determine whether events are triggered or discarded.
- Transformation functions that run before request signing, and are used to modify the headers and body of the request.
- Handler functions that can be used as the target of the event, as opposed to targeting a URL.
All three function types receive the same headers and body as a traditional App Event.
App Event function examples
Examples showcase full functionality of App Event functions.
App Event function templates
Templates allow developers to quickly scaffold an app with App Event functions. These templates provide a starting point with skeleton code — you must add your custom logic to meet your specific use case.
Use case: App Actions
Functions can be linked to and then invoked via App Actions, which provides apps an easy way to expose generic capabilities to their own frontends as well as to other apps.
Similar to App Event functions, App Action functions receive the same headers and body as a traditional App Action.
App Action function examples
Examples showcase full functionality of App Action functions.
App Action function templates
Templates allow developers to quickly scaffold an app with App Action functions. These templates provide a starting point with skeleton code — you must add your custom logic to meet your specific use case.
Working with functions
This document provides an overview of functions, their use cases, and their limitations. Review the working with functions guide to dive deeper on creating, managing, and troubleshooting functions. There are also tutorials on Custom external references and Native external references for those specific use cases.
Networking
Contentful Functions make outbound requests from a fixed set of IP addresses. You can use these addresses to configure allowlists on external services that your functions connect to.
Limitations
Function executions per month and organization are subject to use in accordance with our current Technical Limits and Usage Limits. Additional considerations for developers utilizing functions are listed below.
Functions platform:
- Custom external references run only for uncached requests.
- Custom external references can only be used with short Text or JSON object field types.
- Custom external references allow you to integrate with external GraphQL APIs. You can also integrate with external REST APIs, but you have to provide your own GraphQL server implementation. For more information on the REST API implementation, see our PotterDB for REST example.
- Functions that resolve data in the delivery context are not currently compatible with live updates when using live preview.
Functions execution environment:
- Function code does not have access to the filesystem.
- Functions can handle event payloads less than 32MB in size.
- Requests to and responses from the provided CMA client must be less than 32MB in size. Utilize a
ReadableStreamif uploading an asset that exceeds this size, or instantiate your own client as described in the Using the CMA section below. - Functions have limited CPU and Memory resources available. Exceeding these resources will terminate the function.
Node.js compatibility:
Contentful Functions run in an environment which provides compatibility with many Node.js APIs but differs from the standard Node.js runtime. This means that while many npm packages will work, some relying on specific Node.js APIs might not function as expected. The following table outlines the support status for various Node.js APIs within the Functions runtime:
Using the CMA
The FunctionEventContext — provided to functions invocations for App Events and App Actions, as well as search or lookup invocations for native external references — includes all the information needed to instantiate a contentful-management.js client. This includes HTTP client options, as well as the space ID and environment ID where the function is executed.
To use the CMA, install contentful-management into your project and initialize it like so:
Note that cmaClientOptions is only provided for function types that execute in a management context (App Events, App Actions, and native external references search/lookup). The guard above narrows the type and provides a clear error if the function runs in a context where CMA credentials are not available. For a more complete example, see the App Action function example.
For convenience, a pre-initialized CMA (“plain”) client is also included in the context. It is limited to requests and responses smaller than 32 MiB. This client executes CMA requests using the App Identity of the app that contains the function.
Feedback
Functions are continuously evolving to better meet your needs. We invite you to share your experience using functions and the use cases you’re looking to implement.
Share your feedback here.