diff --git a/docs/_config.yml b/docs/_config.yml
index 67fcf2739..63d00e632 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -13,6 +13,8 @@ collections:
output: false
advanced:
output: false
+ functions:
+ output: false
steps:
output: false
deployments:
@@ -38,10 +40,12 @@ t:
advanced: Advanced concepts
start: Getting started
reference: Reference
+ functions: Custom functions
steps: Workflow steps
deployments: Deployments
contribute: Contributing
deprecated: Deprecated
+ beta: Beta
ja-jp:
basic: 基本的な概念
advanced: 応用コンセプト
@@ -52,6 +56,7 @@ t:
reference: リファレンス
contribute: 貢献
deprecated: 非推奨
+ beta: Beta
# Metadata
repo_name: bolt-js
diff --git a/docs/_functions/creating.md b/docs/_functions/creating.md
new file mode 100644
index 000000000..52cb2b505
--- /dev/null
+++ b/docs/_functions/creating.md
@@ -0,0 +1,20 @@
+---
+title: Creating custom functions
+lang: en
+slug: creating-custom-functions
+order: 1
+---
+
+
+Custom functions allow your app to create and process workflow steps that users can add in [Workflow Builder](https://api.slack.com/workflows).
+
+We recommend using custom functions as a replacement for the [deprecated Workflow Steps from Apps](#steps).
+
+A custom function requires two components:
+
+* [A function definition in the app’s manifest](#defining-custom-functions)
+* [A listener to handle the function execution event](#listening-to-custom-functions)
+
+Read more about custom functions in the [Slack API documentation](https://api.slack.com/automation/functions/custom-bolt).
+
+
diff --git a/docs/_functions/defining.md b/docs/_functions/defining.md
new file mode 100644
index 000000000..371dfa106
--- /dev/null
+++ b/docs/_functions/defining.md
@@ -0,0 +1,44 @@
+---
+title: Defining custom functions
+lang: en
+slug: defining-custom-functions
+order: 2
+---
+
+
+
+To make a custom function available for use in Workflow Builder, the app’s manifest must contain a function definition.
+
+A function’s definition contains information about the function, including its `callback_id`, `input_parameters`, `output_parameters`, as well as display information.
+
+To learn more about defining a function, see the [Slack API documentation](https://api.slack.com/automation/functions/custom-bolt#define-function).
+
+
+
+```json
+"functions": {
+ "sample_function": {
+ "title": "Sample function",
+ "description": "Runs sample function",
+ "input_parameters": {
+ "user_id": {
+ "type": "slack#/types/user_id",
+ "title": "User",
+ "description": "Message recipient",
+ "is_required": true,
+ "hint": "Select a user in the workspace",
+ "name": "user_id"
+ }
+ },
+ "output_parameters": {
+ "user_id": {
+ "type": "slack#/types/user_id",
+ "title": "User",
+ "description": "User that completed the function",
+ "is_required": true,
+ "name": "user_id"
+ }
+ }
+ }
+}
+```
\ No newline at end of file
diff --git a/docs/_functions/listening.md b/docs/_functions/listening.md
new file mode 100644
index 000000000..f16624cbb
--- /dev/null
+++ b/docs/_functions/listening.md
@@ -0,0 +1,32 @@
+---
+title: Listening to custom function executions
+lang: en
+slug: listening-to-custom-functions
+order: 3
+---
+
+
+
+When your custom function is executed as a step in a workflow, your app will receive a [`function_executed`](https://api.slack.com/events/function_executed) event. The callback provided to the `function()` method will be run when this event is received.
+
+The callback is where you can access `inputs`, make third-party API calls, or set the output values that will be available to subsequent workflow steps by mapping values to the `outputs` object.
+
+Your app can call `complete()` to indicate that the function’s execution was successful, or `fail()` to signal that the function failed to complete.
+
+To learn more about listening to custom function executions, see the [Slack API documentation](https://api.slack.com/automation/functions/custom-bolt#listener).
+
+
+
+
+```js
+app.function('sample_function', async ({ client, inputs, fail }) => {
+ try {
+ const { user_id } = inputs;
+ await complete({ outputs: { user_id } });
+ } catch (error) {
+ console.error(error);
+ fail({ error: `Failed to handle a function request: ${error}` });
+ }
+});
+```
+
diff --git a/docs/_functions/responding.md b/docs/_functions/responding.md
new file mode 100644
index 000000000..8e7425e7b
--- /dev/null
+++ b/docs/_functions/responding.md
@@ -0,0 +1,24 @@
+---
+title: Responding to interactivity
+lang: en
+slug: responding-to-interactivity
+order: 4
+---
+
+
+
+Interactive elements provided to the user, via message or modal, from within the `function()` method’s callback are associated with that unique `function_executed` event. This association allows for the completion of functions at a later time, like once the user has clicked a button.
+
+Incoming actions that are associated with a function have the same `inputs`, `complete`, and `fail` utilities as offered by the `function()` method.
+
+To learn more about responding to interactivity, see the [Slack API documentation](https://api.slack.com/automation/functions/custom-bolt#interactivity).
+
+
+
+```js
+// If associated with a function, function-specific utilities are made available
+app.action('approve_button', async ({ complete, fail }) => {
+ // Signal the function has completed once the button is clicked
+ await complete({ outputs: { message: 'Request approved 👍' } });
+});
+```
diff --git a/docs/_includes/sidebar.html b/docs/_includes/sidebar.html
index cb7aacac1..df37df835 100644
--- a/docs/_includes/sidebar.html
+++ b/docs/_includes/sidebar.html
@@ -64,11 +64,26 @@
{% endif %}
+
+