Skip to main content

Documentation Index

Fetch the complete documentation index at: https://algolia.com/llms.txt

Use this file to discover all available pages before exploring further.

Use multifeed compositions to return several independent result sets from a single API request. Each result set, called a feed, can have its own search parameters, filters, and Smart Groups. Multifeed compositions are ideal for federated search experiences that display results from different categories, brands, or content types at the same time.

Use cases

Use multifeed compositions when you need to return multiple independently ranked result sets for the same query in a single request.

Federated search across categories

Show results from different product categories in parallel. For example, when users search for “running”, return separate feeds for running shoes, running apparel, and running accessories. Each feed maintains its own ranking strategy, filters, and promoted items, so category-specific merchandising doesn’t interfere with other results.

Multi-brand or multi-tenant results

Return results grouped by brand, seller, or tenant in a single response. For example, a marketplace can display products from different sellers, where each seller controls their own promoted items and positioning.

Content type segmentation

Separate results by content type—such as products, articles, or videos—while using the same user query. Each feed applies ranking and filtering tailored to its content type. For example, products may prioritize conversion signals, while articles prioritize recency or engagement.

How multifeed works

A multifeed composition defines multiple feeds in the behavior.multifeed object. Each feed:
  • Has a unique identifier (feedID)
  • Contains its own behavior, typically an injection with search parameters and Smart Groups
  • Returns an independent result set in the response
All feeds run in parallel, sharing the same base query but applying their own filters and injection logic. Each feed is standalone, with its own Smart Groups injected into its .

Define a multifeed composition

Use the Composition API to create a multifeed composition. The following example creates a composition that returns three separate feeds for different content types: products, articles, and videos.
var response = await client.PutCompositionAsync(
  "my-compo",
  new Composition
  {
    ObjectID = "my-compo",
    Name = "my composition",
    Behavior = new CompositionBehavior(
      new CompositionMultifeedBehavior
      {
        Multifeed = new Multifeed
        {
          Feeds = new Dictionary<string, FeedInjection>
          {
            {
              "products",
              new FeedInjection
              {
                Injection = new Injection
                {
                  Main = new InjectionMain
                  {
                    Source = new InjectionMainSource(
                      new InjectionMainSearchSource
                      {
                        Search = new MainSearch
                        {
                          Index = "products",
                          Params = new MainInjectionQueryParameters { HitsPerPage = 12 },
                        },
                      }
                    ),
                  },
                  InjectedItems = new List<InjectionInjectedItem>
                  {
                    new InjectionInjectedItem
                    {
                      Key = "featured-products",
                      Source = new InjectedItemSource(
                        new InjectedItemSearchSource
                        {
                          Search = new InjectedItemSearch
                          {
                            Index = "products",
                            Params = new BaseInjectionQueryParameters
                            {
                              Filters = "featured:true",
                            },
                          },
                        }
                      ),
                      Position = 0,
                      Length = 2,
                    },
                  },
                },
              }
            },
            {
              "articles",
              new FeedInjection
              {
                Injection = new Injection
                {
                  Main = new InjectionMain
                  {
                    Source = new InjectionMainSource(
                      new InjectionMainSearchSource
                      {
                        Search = new MainSearch
                        {
                          Index = "articles",
                          Params = new MainInjectionQueryParameters
                          {
                            HitsPerPage = 5,
                            AttributesToRetrieve = new List<string>
                            {
                              "title",
                              "excerpt",
                              "publishedAt",
                            },
                          },
                        },
                      }
                    ),
                  },
                  InjectedItems = new List<InjectionInjectedItem>
                  {
                    new InjectionInjectedItem
                    {
                      Key = "editorial-picks",
                      Source = new InjectedItemSource(
                        new InjectedItemSearchSource
                        {
                          Search = new InjectedItemSearch
                          {
                            Index = "articles",
                            Params = new BaseInjectionQueryParameters
                            {
                              Filters = "editorial_pick:true",
                            },
                          },
                        }
                      ),
                      Position = 0,
                      Length = 1,
                    },
                  },
                },
              }
            },
            {
              "videos",
              new FeedInjection
              {
                Injection = new Injection
                {
                  Main = new InjectionMain
                  {
                    Source = new InjectionMainSource(
                      new InjectionMainSearchSource
                      {
                        Search = new MainSearch
                        {
                          Index = "videos",
                          Params = new MainInjectionQueryParameters
                          {
                            HitsPerPage = 3,
                            AttributesToRetrieve = new List<string>
                            {
                              "title",
                              "thumbnail",
                              "duration",
                            },
                          },
                        },
                      }
                    ),
                  },
                },
              }
            },
          },
          FeedsOrder = new List<string> { "products", "articles", "videos" },
        },
      }
    ),
  }
);

Key parameters

  • feeds: A map of feed definitions, where each key is the feed ID and each value is a behavior, typically an injection
  • feedsOrder (optional): An array specifying the order feeds appear in the response. If omitted, feeds return in alphabetical order by feed ID

Query a multifeed composition

Query a multifeed composition the same way as a standard composition using the Run a Composition endpoint. Use the optional feedsOrder parameter to reorder, enable, or disable feeds at run time, overriding the value defined in the composition itself.
var response = await client.SearchAsync<Hit>(
  "foo",
  new RequestBody
  {
    Params = new Params { Query = "batman" },
    FeedsOrder = new List<string> { "feed-movies", "feed-comics" },
  }
);
The response includes one result set per feed, and the feeds are ordered based on the feedsOrder value. Each feed’s result set includes the corresponding feedID and Smart Groups injected into its , with deduplication applied within that feed.
JSON
{
  "results": [
    {
      "feedID": "products",
      "hits": [
        {
          "objectID": "prod-123",
          "title": "Professional Camera",
          "featured": true
        },
        {
          "objectID": "prod-456",
          "title": "Camera Lens Kit",
          "featured": true
        },
        { "objectID": "prod-789", "title": "Camera Tripod" },
        { "objectID": "prod-012", "title": "Memory Card" }
      ],
      "nbHits": 87,
      "page": 0,
      "nbPages": 8,
      "hitsPerPage": 12,
      "query": "camera"
    },
    {
      "feedID": "articles",
      "hits": [
        {
          "objectID": "article-111",
          "title": "How to Choose Your First Camera",
          "excerpt": "A beginner's guide...",
          "editorial_pick": true
        },
        {
          "objectID": "article-222",
          "title": "Camera Settings Guide",
          "excerpt": "Master exposure..."
        },
        {
          "objectID": "article-333",
          "title": "Camera Maintenance Tips",
          "excerpt": "Keep your equipment..."
        }
      ],
      "nbHits": 24,
      "page": 0,
      "nbPages": 5,
      "hitsPerPage": 5,
      "query": "camera"
    },
    {
      "feedID": "videos",
      "hits": [
        {
          "objectID": "video-555",
          "title": "Camera Setup Tutorial",
          "duration": 420
        },
        {
          "objectID": "video-666",
          "title": "Product Review: Latest Camera",
          "duration": 615
        }
      ],
      "nbHits": 15,
      "page": 0,
      "nbPages": 5,
      "hitsPerPage": 3,
      "query": "camera"
    }
  ]
}

Deduplication and facet management

Each feed in a multifeed composition is processed independently as a complete result set. This means:
  • Deduplication applies within each feed according to your deduplication strategy, preventing duplicate items between Smart Groups and in that feed
  • Facet values are computed based on each feed’s configuration and results
  • Pagination works independently for each feed
Items can appear in multiple feeds if they match the criteria for different feeds. For example, the same product could appear in both a “featured products” feed and a “new arrivals” feed.

Integrate with InstantSearch

Before integrating multifeed compositions with InstantSearch, make sure you’ve completed the base composition setup, including installing the Composition API client and configuring your compositionID. Multifeed support requires these versions of the InstantSearch libraries:
  • React InstantSearch: version 7.32.0 or later
  • InstantSearch.js: version 4.96.0 or later
  • Vue InstantSearch: version 4.26.0 or later
Use the Feeds widget to render each feed from a multifeed composition as an independent result set. Each feed gets its own widget scope, so widgets like Hits or RefinementList inside a feed only see that feed’s results.
import { Feeds, Hits, Highlight } from "react-instantsearch";

function Search() {
  return (
    <Feeds
      searchScope="global"
      renderFeed={({ feedID }) => (
        <section>
          <h2>{feedID}</h2>
          {feedID === "products" ? (
            <Hits
              hitComponent={({ hit }) => (
                <article>
                  <Highlight attribute="name" hit={hit} />
                  <p>{hit.price}</p>
                </article>
              )}
            />
          ) : (
            <Hits
              hitComponent={({ hit }) => (
                <article>
                  <Highlight attribute="title" hit={hit} />
                  <p>{hit.excerpt}</p>
                </article>
              )}
            />
          )}
        </section>
      )}
    />
  );
}

useFeeds hook (React)

The useFeeds Hook gives you direct access to the list of feed IDs without rendering feeds. This is useful for building custom UI around feeds, such as tab navigation or feed counts.
React
import { useFeeds, Feeds } from "react-instantsearch";

function TabbedFeeds() {
  const { feedIDs } = useFeeds({ searchScope: "global" });
  const [activeTab, setActiveTab] = useState(feedIDs[0]);

  return (
    <>
      <nav>
        {feedIDs.map((id) => (
          <button key={id} onClick={() => setActiveTab(id)}>
            {id}
          </button>
        ))}
      </nav>
      <Feeds
        searchScope="global"
        renderFeed={({ feedID }) => (
          <div style={{ display: feedID === activeTab ? "block" : "none" }}>
            <Hits />
          </div>
        )}
      />
    </>
  );
}

Transform feeds

All three InstantSearch flavors accept a transformFeeds option that lets you reorder or filter feeds on the client side. The function receives an array of feed IDs and returns a new array.
React
<Feeds
  searchScope="global"
  transformFeeds={(feedIDs) => feedIDs.filter((id) => id !== "internal")}
  renderFeed={({ feedID }) => (
    <section>
      <Hits />
    </section>
  )}
/>

Limits and considerations

  • You can’t use sorting strategies with multifeed compositions
  • All feeds share the same base and parameters from the request
  • Pagination applies independently to each feed
Last modified on May 7, 2026