Create step-by-step guides
The developer portal beta is approaching end of life.
Use Realm and Reunite instead. Read the migration guide.
With UI components built into the Developer portal, you can create interactive step-by-step guides to teach your API consumers how to work with your APIs. This component lets you embed the Try it API console from Redocly Reference into any MDX page in your portal. Your API consumers can then send requests and receive responses from the API directly in the guide by following along with your examples. Similar to method chaining, you can connect the response data with the request data in subsequent steps.
The key point of a step-by-step guide is the order in which the steps must be executed. In some cases, this order is strictly determined by the design of an API or by the consumer's goal. The OpenApiTryIt
component supports conditional content and makes it possible to indicate that a step depends on one or more previous steps in the guide.
Prerequisites
We're starting with the assumption that you already have a Developer portal project set up. To create an interactive step-by-step guide in your portal, you need the following:
A valid OpenAPI definition for the API(s) you want to describe in the guide. The OpenAPI definition must be listed in the oasDefinitions section of your
siteConfig.yaml
file. For every OpenAPI definition you plan to use, you need thedefinitionId
from theoasDefinitions
section.A working server and authentication configuration for the API(s) you want to describe in the guide. This is required in order to successfully send requests and receive responses from the APIs in the
OpenApiTryIt
component.
Plan the content for the guide
Before you start writing your step-by-step guide, it's a good idea to plan its outline.
First, be clear about the purpose of your guide and specific about what you want to teach the readers. It's useful to specify the expected level of expertise or the target audience at the beginning of your guide. If possible, include links to resources for other types of readers who might want to learn more about your APIs. You should also decide on a use-case scenario to show in your guide. To help your audience understand your APIs better, choose common scenarios that showcase typical tasks consumers do with your APIs.
Next, think about the order of steps. Try to make it logical so that the user flow makes sense when readers follow your guide. You should define dependencies for each step you want to include in your guide. In this context, "dependencies" refer to any element (e.g. request parameter or response field) that must be present in a specific step to successfully complete an action.
Finally, make sure that the examples you use in your guide are correct, and that the readers can execute them by sending example requests to your server.
Import components for the guide
After setting up your OpenAPI definition(s) and planning the content outline of your guide, create the guide as an MDX file in your portal project.
Components must be imported in the following format:
import { componentName } from '@redocly/developer-portal/ui';
This example shows an MDX file with imported components for step-by-step guides:
import { OpenApiTryIt, Alert, ExplainStep, scrollToHeading } from '@redocly/developer-portal/ui';
# Example MDX page title
Example text
Set up steps with OpenApiTryIt
For every step that shows an example request to your API, use the OpenApiTryIt
component.
In the component, you must specify the OpenAPI definition (by its
definitionId
from thesiteConfig.yaml
file) and the operation (by itsoperationId
from the OpenAPI document).Next, you must assign a custom ID to the component instance. This is required to distinguish between multiple component instances in the guide.
To define dependencies between the steps (e.g. to show that Step 2 requires Step 1), use
needs
andplaceholder
component properties. Underneeds
, list one or more custom ID values of previousOpenApiTryIt
instances that are required for the current step. Underplaceholder
, use a function to describe the condition(s) that must be fulfilled to proceed to the next step. This placeholder description remains visible until all specified conditions are met.Depending on the example you want to show, use any of the supported component properties (
properties
,parameters
,serverVariables
,securityDefaults
) to set the default values. Those preset values are automatically used when a reader sends an example request from the component.Optionally, use the
onResponse
property in the component to define what happens after receiving the response and/or how to handle the received data.
Example 1: Use OpenApiTryIt
In the following example, we set up the first step in the guide (identified by id="step-1"
) and use optional properties
, parameters
and onResponse
objects in the OpenApiTryIt
component.
properties
sets the default values for request body properties used in the example requestparameters
sets the default values for request parameters used in the example requestonResponse
uses thescrollToHeading
component to redirect the reader to a specific heading on the page after receiving the response.
Example: Add Step 1
# Step 1
In this step, we're creating a new user account.
<OpenApiTryIt
definitionId="stepByStep"
operationId="CreateUser"
id="step-1"
properties={{
firstName: "John",
lastName: "Smith"
}}
parameters={{
header: {
'Organization-Id': 'My-Header'
}
}}
onResponse={({ response }) => {
if (response.ok) {
scrollTo(0, document.querySelector('#step-2').offsetTop - 20, { behavior: 'smooth' })
}
}}
/>
Then, we add the second step to the guide (identified by id="step-2"
). With needs
and placeholder
, we indicate that the first step is required for the second step.
needs
contains theid
of the required step(s) - in this case, it's 'step-1'placeholder
contains a function that will display theAlert variant="danger"
component with the specified text until the reader completes Step 1Alert variant="success"
will be displayed after the reader successfully receives a response in Step 1
Function names can contain letters, numbers, underscores and dollar signs, but not hyphens.
That is why the value of id
(step-1) is different from the function name in properties
and placeholder
(step1).
Example: Add Step 2
# Step 2
In this step, we're changing the account status to give the user administrator privileges.
<OpenApiTryIt
definitionId="stepByStep"
operationId="UpdateUser"
id="step-2"
needs={['step-1']}
properties={(step1) => ({
userId: step1.response.body.data.user.id,
status: "admin",
})}
placeholder={(step1) => {
if (!step1) {
return (
<Alert variant="danger">
Please complete Step 1 first. We need the user ID (<strong><i>step1.response.body.data.user.id</i></strong>) from the response body in Step 1 for this request. This ID tells the API which user account to update.
</Alert>
);
} else {
return (
<Alert variant="success">
<strong>You can now send the request to change account status for the {step1.response.body.data.user.id} user.</strong>
</Alert>
)
}
}}
onResponse={({ response }) => {
if (response.ok) {
scrollTo(0, document.querySelector('#step-3').offsetTop - 20, { behavior: 'smooth' })
}
}}
/>
Add context with ExplainStep
In addition to defining the dependencies between steps in the OpenApiTryIt
component, you can use the ExplainStep
component. With this component, you can highlight which elements are required in each step, and describe the relationships between steps. Like with OpenApiTryIt
, you can use multiple instances of the ExplainStep
component in your guide.
Connect the
ExplainStep
component to one or moreOpenApiTryIt
instances. List the custom ID of eachOpenApiTryIt
step in theneeds
component property.Use the
placeholder
component property to add context and descriptions for every step listed inneeds
. The contents ofplaceholder
should be a function that defines what your readers see on the page based on previously completed steps.
Example 2: Use ExplainStep
Expand on the previous example by inserting the ExplainStep
component after the second step. We're using this component to explain why Step 1 and Step 2 are required for Step 3, and to warn the readers that they must complete those steps first.
ExplainStep
has its own custom ID (id="explain-step-1"
) to prevent conflicts with other instances in the guideplaceholder
contains a function that will display theAlert variant="danger"
component with the specified text until the reader completes Step 1 and Step 2- if all previous steps are completed,
Alert variant="success"
will be displayed.
Example: Add context before Step 3
# Step 1
In this step, we're creating a new user account.
<OpenApiTryIt
definitionId="stepByStep"
operationId="CreateUser"
id="step-1"
properties={{
firstName: "John",
lastName: "Smith"
}}
parameters={{
header: {
'Organization-Id': 'My-Header'
}
}}
onResponse={({ response }) => {
if (response.ok) {
scrollTo(0, document.querySelector('#step-2').offsetTop - 20, { behavior: 'smooth' })
}
}}
/>
# Step 2
In this step, we're changing the account status to give the user administrator privileges.
<OpenApiTryIt
definitionId="stepByStep"
operationId="UpdateUser"
id="step-2"
needs={['step-1']}
properties={(step1) => ({
userId: step1.response.body.data.user.id,
status: "admin",
})}
placeholder={(step1) => {
if (!step1) {
return (
<Alert variant="danger">
Please complete Step 1 first. We need the user ID (<strong><i>step1.response.body.data.user.id</i></strong>) from the response body in Step 1 for this request. This ID tells the API which user account to update.
</Alert>
);
} else {
return (
<Alert variant="success">
<strong>You can now send the request to change account status for the {step1.response.body.data.user.id} user.</strong>
</Alert>
)
}
}}
onResponse={({ response }) => {
if (response.ok) {
scrollTo(0, document.querySelector('#step-3').offsetTop - 20, { behavior: 'smooth' })
}
}}
/>
# Step 3
<ExplainStep
needs={['step-1', 'step-2']}
id="explain-step-1"
placeholder={(step1,step2) => {
if (!step1) {
return (
<Alert variant="danger">
You must create a user account first. Please complete Step 1. The user ID from the Step 1 response body is required to send a request in Step 2.
</Alert>
)
} else if (!step2) {
return (
<Alert variant="danger">
You must change the user status before proceeding with Step 3. Please complete Step 2. The user account must have administrator privileges to send a request in Step 3.
</Alert>
)
} else {
return (
<Alert variant="success">
<strong>You have successfully completed Step 1 and Step 2!</strong><br />
Now you can proceed to Step 3.
</Alert>
)
}
}}
/>
Complete the step-by-step guide
After you add the OpenApiTryIt
and ExplainStep
instances to your guide, make sure that their dependencies are correctly defined. Check that the id
of each instance matches the needs
and placeholder
values of other instances that refer to it.
In previous sections, we added Step 1 and Step 2 to our example guide, and introduced the requirements for Step 3. The following example shows the full step-by-step guide with three steps.
Example step-by-step guide with 3 steps
import { H3, OpenApiTryIt, Alert, ExplainStep, scrollToHeading } from '@redocly/developer-portal/ui';
# Create a shared administrator account
In this step-by-step guide, we will create a shared administrator account for the organization.
# Step 1
In this step, we're creating a new user account.
<OpenApiTryIt
definitionId="stepByStep"
operationId="CreateUser"
id="step-1"
properties={{
firstName: "John",
lastName: "Smith"
}}
parameters={{
header: {
'Organization-Id': 'My-Header'
}
}}
onResponse={({ response }) => {
if (response.ok) {
scrollTo(0, document.querySelector('#step-2').offsetTop - 20, { behavior: 'smooth' })
}
}}
/>
# Step 2
In this step, we're changing the account status to give the user administrator privileges.
<OpenApiTryIt
definitionId="stepByStep"
operationId="UpdateUser"
id="step-2"
needs={['step-1']}
properties={(step1) => ({
userId: step1.response.body.data.user.id,
status: "admin",
})}
placeholder={(step1) => {
if (!step1) {
return (
<Alert variant="danger">
Please complete Step 1 first. We need the user ID (<strong><i>step1.response.body.data.user.id</i></strong>) from the response body in Step 1 for this request. This ID tells the API which user account to update.
</Alert>
);
} else {
return (
<Alert variant="success">
<strong>You can now send the request to change account status for the {step1.response.body.data.user.id} user.</strong>
</Alert>
)
}
}}
onResponse={({ response }) => {
if (response.ok) {
scrollTo(0, document.querySelector('#step-3').offsetTop - 20, { behavior: 'smooth' })
}
}}
/>
# Step 3
In this step, we're setting the scope of administrator privileges to the entire organization.
<ExplainStep
needs={['step-1', 'step-2']}
id="explain-step-1"
placeholder={(step1,step2) => {
if (!step1) {
return (
<Alert variant="danger">
You must create a user account first. Please complete Step 1. The user ID from the Step 1 response body is required to send a request in Step 2.
</Alert>
)
} else if (!step2) {
return (
<Alert variant="danger">
You must change the user status before proceeding with Step 3. Please complete Step 2. The user account must have administrator privileges to send a request in Step 3. We also need the list of permissions from the Step 2 response body for this request.
</Alert>
)
} else {
return (
<Alert variant="success">
<strong>You have successfully completed Step 1 and Step 2!</strong><br />
Now you can proceed to Step 3.
</Alert>
)
}
}}
/>
<OpenApiTryIt
definitionId="stepByStep"
operationId="SetScope"
id="step-3"
needs={['step-1', 'step-2']}
properties={(step1, step2) => ({
userId: step1.response.body.data.user.id,
permissions: step2.response.body.permissions
scope: "org",
})}
placeholder={(step1, step2) => {
const text = step1 || step2 ? 'Complete 1 remaining step' : 'Complete the 2 steps above';
return <Alert variant="warning">{text}</Alert>
}}
/>
Preview and test the guide
When you have added all the steps in the desired order, save the changes to your MDX file. Start the portal build. When the build is complete, navigate to the page that contains your new step-by-step guide. Go through all the steps defined in your guide and test out the examples to make sure they're functioning properly.
For a working example of a step-by-step guide in the developer portal, check the Rebilly payment form tutorial.