<link rel="stylesheet" href="/_merged_assets/_static/search/noscript.css">
Apollo Elements Apollo Elements Guides API Blog Toggle darkmode


The core of Apollo Elements is a set of JavaScript classes that implement the ReactiveController interface. This means that the essential operating logic of queries, mutations, and subscriptions is encapsulated in independent objects, and that elements implementing ReactiveControllerHost (e.g. LitElement) work with them straight-away. Apollo Element is more than just "Apollo for Lit", though - the core classes form the basis for all our framework integrations, from custom element mixins, to hybrids descriptor factories, to haunted hooks.

This also introduces a separation between GraphQL operations (like queries or mutations) and the web components which host them. Previous versions of Apollo Elements strongly tied each GraphQL document to a single custom element, meaning if you wanted to have several queries in one component, the component either needed to define those queries as children, or combine the queries into a single document.

npm i -S @apollo-elements/core
yarn add @apollo-elements/core
pnpm add @apollo-elements/core
import {
} from '@apollo-elements/core';

import { customElement, state, query } from 'lit/decorators.js';
import { css, html, LitElement } from 'lit';
import { classMap } from 'lit/directives/class-map.js';

import { ProfileQuery } from './Profile.query.graphql.js';
import { UpdateProfileMutation } from './UpdateProfile.mutation.graphql.js';
import { FriendCameOnlineSubscription } from './FriendCameOnline.subscription.graphql.js';

import { Snackbar } from '@material/mwc-snackbar';
import '@material/mwc-textfield';

class ProfileHome extends LitElement {
  profile = new ApolloQueryController(this, ProfileQuery);

  updateProfile = new ApolloMutationController(this, UpdateProfileMutation, {
    refetchQueries: [{ query: ProfileQuery }],
    awaitRefetchQueries: true,

  friendCameOnline = new ApolloSubscriptionController(this, FriendCameOnlineSubscription, {
    onData: () => this.snackbar.show(),

  @query('mwc-snackbar') snackbar: Snackbar;

  render() {
    return html`
      <mwc-snackbar labeltext="${this.friendCameOnline.data?.nick} came online"></mwc-snackbar>
      <header class=${classMap({ loading: this.profile.loading })}>
        <h1>Welcome, ${this.profile.data?.profile?.nick}</h1>
            label="Edit Nick"

  onChange(event) {
    const nick = event.target.value
    this.updateProfile.mutate({ variables: { nick } });