Skip to main content

Overview

The Web Stories plugin provides a powerful Gutenberg block (web-stories/embed) that supports multiple display modes for embedding stories in your WordPress content.

Block Types

The Web Stories block supports three distinct modes:

Single Story

Embed a single story by URL

Latest Stories

Display recently published stories

Selected Stories

Show specific curated stories

Single Story Embed

Embed a single story using its URL.

Block Usage

1

Add the Web Stories Block

In the block editor, click the ”+” button and search for “Web Stories”
2

Enter Story URL

Paste the URL of the story you want to embed
3

Configure Display

Adjust width, height, and alignment options

Block Attributes

block.json
{
  "url": "string",
  "title": "string",
  "poster": "string",
  "width": 360,
  "height": 600,
  "align": "none"
}

Alignment Options

The block supports multiple alignment options:
'supports' => [
    'align' => ['wide', 'full', 'left', 'right', 'center']
]

Latest Stories Block

Automatically display your most recent stories.

Configuration Options

  • Number of Stories - How many stories to show (1-20)
  • View Type - circles, carousel, grid, or list
  • Number of Columns - Columns for grid view (1-4)
  • Order By - Sort by date or title
  • Order - Ascending or descending

Block Code Example

Web_Stories_Block.php
if ( 'latest-stories' === $attributes['blockType'] ) {
    $story_attributes = [
        'view_type'          => $attributes['viewType'] ?? '',
        'archive_link_label' => $attributes['archiveLinkLabel'] ?? __( 'View all stories' ),
        'circle_size'        => $attributes['circleSize'] ?? 96,
        'image_alignment'    => $attributes['imageAlignment'] ?? 96,
        'number_of_columns'  => $attributes['numOfColumns'] ?? 2,
    ];
    
    return ( new Story_Query( $story_attributes, $query_args ) )->render();
}

Query Arguments

The block constructs WP_Query arguments based on settings:
Web_Stories_Block.php
$query_args = [
    'post_type'        => 'web-story',
    'post_status'      => 'publish',
    'posts_per_page'   => $attributes['numOfStories'],
    'order'            => strtoupper( $attributes['order'] ),
    'orderby'          => 'title' === $attributes['orderby'] ? 'post_title' : 'post_date',
    'suppress_filters' => false,
    'no_found_rows'    => true,
];

Selected Stories Block

Display a curated collection of specific stories.

Story Selection

1

Choose Block Type

Select “Selected Stories” in the block settings
2

Pick Stories

Use the story picker to select up to 20 stories
3

Arrange Order

Drag and drop to reorder your selected stories
4

Configure Display

Choose view type and display options

Selected Stories Query

Web_Stories_Block.php
if ( 'selected-stories' === $attributes['blockType']
    && ! empty( $attributes['stories'] ) ) {
    $query_args['post__in'] = $attributes['stories'];
    $query_args['orderby']  = 'post__in';
}
The post__in ordering preserves the exact order you selected in the block editor.

View Types

Stories can be displayed in four different layouts:
Circular thumbnails in a horizontal carousel layout. Perfect for Instagram-style story browsing.
  • Circle size: 80-200px
  • Horizontal scrolling
  • Optimized for mobile

Block Context

The block uses WordPress block context for query loops:
block.json
"usesContext": ["postId", "postType", "queryId"]
Web_Stories_Block.php
if ( isset( $block->context['postType'], $block->context['postId'] )
    && 'web-story' === $block->context['postType'] ) {
    
    $story = new Story();
    $story->load_from_post( get_post( $block->context['postId'] ) );
    
    return $this->render_story( $story, $attributes );
}

Taxonomy Filtering

Filter stories by taxonomies in the block:
Web_Stories_Block.php
if ( ! empty( $attributes['taxQuery'] ) ) {
    $query_args['tax_query'] = [];
    
    foreach ( $attributes['taxQuery'] as $taxonomy => $terms ) {
        if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) {
            $query_args['tax_query'][] = [
                'taxonomy'         => $taxonomy,
                'terms'            => array_filter( array_map( '\intval', $terms ) ),
                'include_children' => false,
            ];
        }
    }
}

Block Registration

The block is registered with a render callback:
Web_Stories_Block.php
register_block_type_from_metadata(
    $base_path,
    [
        'attributes'      => [ /* ... */ ],
        'render_callback' => [ $this, 'render_block' ],
        'editor_script'   => 'web-stories-block',
        'editor_style'    => 'web-stories-block',
    ]
);

Field State Configuration

Control which story fields are visible:
Web_Stories_Block.php
public function get_mapped_field_states(): array {
    $controls = [
        'show_title'        => 'title',
        'show_author'       => 'author',
        'show_excerpt'      => 'excerpt',
        'show_date'         => 'date',
        'show_archive_link' => 'archive_link',
        'sharp_corners'     => 'sharp_corners',
    ];
    
    $controls_state = [];
    foreach ( $controls as $control => $field ) {
        $key = 'show_' . $field;
        $controls_state[ $control ] = $this->block_attributes['fieldState'][ $key ] ?? false;
    }
    
    return $controls_state;
}

JavaScript Configuration

The block editor receives configuration via localized script:
Web_Stories_Block.php
wp_localize_script(
    'web-stories-block',
    'webStoriesBlockSettings',
    [
        'config' => [
            'maxNumOfStories' => 20,
            'archiveURL'      => get_post_type_archive_link( 'web-story' ),
            'api' => [
                'stories' => '/web-stories/v1/web-story/',
                'users'   => '/web-stories/v1/users/',
            ],
        ],
    ]
);

Best Practices

  • Limit the number of stories displayed (recommended: 5-10)
  • Use no_found_rows => true to skip pagination queries
  • Enable thumbnail caching with update_post_thumbnail_cache()
  • Choose view type based on content context
  • Use circles/carousel for sidebar or narrow areas
  • Use grid/list for main content areas
  • Show metadata (author, date) for editorial content
  • Provide meaningful archive link labels
  • Ensure story titles are descriptive
  • Use proper heading hierarchy

Next Steps

Widgets

Display stories in widget areas

Archive Pages

Configure story archive display

Build docs developers (and LLMs) love