## File: README.md

# GraphQL IDE Monorepo

> **Security Notice:** All versions of `graphiql` < `1.4.7` are vulnerable to an
> XSS attack in cases where the GraphQL server to which the GraphiQL web app
> connects is not trusted. Learn more
> [in the graphiql `security` docs directory](docs/security)

> **Looking for the [GraphiQL Docs?](packages/graphiql/README.md)**: This is the
> root of the monorepo! The full GraphiQL docs are located at
> [`packages/graphiql`](packages/graphiql)

[](https://github.com/graphql/graphiql/actions?query=workflow%3A%22Node.JS+CI%22)
[](https://pkg.pr.new/~/graphql/graphiql)
[](https://discord.gg/NP5vbPeUFp)
[](https://codecov.io/gh/graphql/graphiql)


[](https://snyk.io/test/github/graphql/graphiql)
[](https://bestpractices.coreinfrastructure.org/projects/3887)

## Overview

GraphiQL (pronounced like "graphical") is the reference implementation of this
monorepo, GraphQL IDE, an official project under the GraphQL Foundation. The
code uses the permissive MIT license.

Whether you want a simple GraphiQL IDE instance for your server, or a more
advanced web or desktop GraphQL IDE experience for your framework or plugin, or
you want to build an IDE extension or plugin, you've come to the right place!

The purpose of this monorepo is to give the GraphQL Community:

- a to-specification official language service (see:
  [API Docs](https://graphiql-test.netlify.app/typedoc))
- a comprehensive LSP server and CLI service for use with IDEs
- a codemirror mode
- a monaco mode (in the works)
- an example of how to use this ecosystem with GraphiQL.
- examples of how to implement or extend GraphiQL.

## [`graphiql`](packages/graphiql#readme)


> [](https://npmjs.com/graphiql)
> 
> 
> 
> 
> 



_/ˈɡrafək(ə)l/_ A graphical interactive in-browser GraphQL IDE.
[Try the live demo](https://graphql.org/swapi-graphql). We also have
[a demo using our latest netlify build](http://graphiql-test.netlify.app) for
the `main` branch.

The GraphiQL IDE, implemented in React, currently using
[GraphQL mode for CodeMirror](packages/codemirror-graphql#readme) &
[GraphQL Language Service](packages/graphql-language-service#readme).

**Learn more about
[GraphiQL in `packages/graphiql/README.md`](packages/graphiql#readme)**

## [`monaco-graphql`](packages/monaco-graphql#readme)

[](https://npmjs.com/monaco-graphql)




Provides monaco editor with a powerful, schema-driven graphql language mode.
Uses the `graphql-language-service`directly.

See the [webpack example](examples/monaco-graphql-webpack#readme) for a plain
javascript demo using GitHub API

## [`codemirror-graphql`](packages/codemirror-graphql#readme)

[](https://npmjs.com/codemirror-graphql)






Provides CodeMirror 5 with a parser mode for GraphQL along with a live linter and
typeahead hinter powered by your GraphQL Schema. Uses the
`graphql-language-service`.

## [`cm6-graphql`](packages/cm6-graphql#readme)

[](https://npmjs.com/cm6-graphql)




Provides CodeMirror 6 with a full-featured language mode for GraphQL. Uses the `graphql-language-service`.

## [`graphql-language-service`](packages/graphql-language-service#readme)

[](https://npmjs.com/graphql-language-service)



Provides language services for
[`graphql-language-service-server`](packages/graphql-language-service-server#readme)
[`codemirror-graphql`](packages/codemirror-graphql) and
[`monaco-graphql`](packages/monaco-graphql). Previously published separately as
the now-retired `graphql-language-service-interface`,
`graphql-language-service-parser`, `graphql-language-service-utils` and
`graphql-language-service-types`.

## [`graphql-language-service-server`](packages/graphql-language-service-server#readme)

[](https://npmjs.com/graphql-language-service-server)



Provides language services for LSP-based IDE extensions using the
`graphql-language-service`

## [`graphql.vscode-graphql`](packages/vscode-graphql#readme)

An example implementation of `graphql-language-service-server` for Visual Studio
Code. Available
[on the marketplace](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql).
OVSX fix is pending.

## [`graphql.vscode-graphql-syntax`](packages/vscode-graphql-syntax#readme)

A new syntax highlighting-only extension for vscode to be used by other vscode
extensions.

## [`graphql.vscode-graphql-execution`](packages/vscode-graphql-execution#readme)

An extension for vscode-graphql that allows inline query execution.

## [`graphql-language-service-cli`](packages/graphql-language-service-cli#readme)

[](https://npmjs.com/graphql-language-service-cli)



Provides a CLI for the language service server.

## Browser & Runtime Support

Many of these packages need to work in multiple environments.

By default, all typescript packages target `es6`.

`graphql-language-service-server` and `graphql-language-service-cli` are made
for the node runtime, so they target `es2017`

`codemirror-graphql` and the `graphiql` browser bundle use the
[`.browserslistrc`](./.browserslistrc), which targets modern browsers to keep
bundle size small and keep the language services performant where async/await is
used, and especially to avoid the requirement of `regenerator-runtime` or
special babel configuration.

### [`.browserslistrc`](./.browserslistrc):

```
last 2 versions
Firefox ESR
not dead
not IE 11
not ios 10
maintained node versions
```

To be clear, we do _not_ support Internet Explorer or older versions of
evergreen browsers.

## Development

To get setup for local development of this monorepo, refer to
[DEVELOPMENT.md](./DEVELOPMENT.md)

# Contributing to this repo

This is an open source project, and we welcome contributions. Please see
[CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute.

This repository is managed by EasyCLA. Project participants must sign the free
[GraphQL Specification Membership agreement](https://preview-spec-membership.graphql.org)
before making a contribution. You only need to do this one time, and it can be
signed by
[individual contributors](http://individual-spec-membership.graphql.org) or
their [employers](http://corporate-spec-membership.graphql.org).

To initiate the signature process please open a PR against this repo. The
EasyCLA bot will block the merge if we still need a membership agreement from
you.

Please note that EasyCLA is configured to accept commits from certain GitHub
bots. These are approved on an exception basis once we are confident that any
content they create is either unlikely to consist of copyrightable content or
else was written by someone who has already signed the CLA (e.g., a project
maintainer). The bots that have currently been approved as exceptions are:

- github-actions (exclusively for the `changesets` Action)

You can find
[detailed information here](https://github.com/graphql/graphql-wg/tree/main/membership).
If you have issues, please email
[operations@graphql.org](mailto:operations@graphql.org).

## Maintainers

Maintainers of this repository regularly review PRs and issues and help advance
the GraphiQL roadmap

### Alumni

Without these amazing past maintainers, where would we be?!

- [@leebyron](https://github.com/leebyron) - original author of all libraries
- [@asiandrummer](https://github.com/asiandrummer) - original creator of
  GraphiQL
- [@wincent](https://github.com/wincent) - early co-author and maintainer
- [@lostplan](https://github.com/lostplan) - maintained the language service
  ecosystem until about 2017
- [@IvanGoncharov](https://github.com/ivangoncharov) - maintainer and
  transitional mentor to @acao and others
- [@orta](https://github.com/orta) - has helped with so many parts of the
  project over the years, and provided the original redesign!
- [@divyenduz](https://github.com/divyenduz) - the original creator of
  `vscode-graphql`, and contributor to much of the ecosystem. Thanks Divy!

### Active

Maintainers who are currently active (to varying degrees, please contact us via
our discord channels!):

- [@imolorhe](https://github.com/imolorhe)
- [@yoshiakis](https://github.com/yoshiakis)
- [@urigo](https://github.com/urigo)
- [@timsuchanek](https://github.com/timsuchanek)
- [@thomasheyenbrock](https://github.com/thomasheyenbrock)
- [@n1ru4l](https://github.com/n1ru4l)
- [@acao](https://github.com/acao)
- [@stonexer](https://github.com/stonexer)
- [@dimaMachina](https://github.com/dimaMachina)
- [@dotansimha](https://github.com/dotansimha)
- [@saihaj](https://github.com/saihaj)
- [@jonathanawesome](https://github.com/jonathanawesome)
- [@cshaver](https://github.com/cshaver)
- [@trevor-scheer](https://github.com/trevor-scheer)

> Thank you graphql community for all the help & support! I did it all for you,
> and I couldn't have done it without you ❤️ - @acao

### Fielding Proposals!

The door is open for proposals for the new GraphiQL Plugin API, and other ideas
on how to make the rest of the IDE ecosystem more performant, scalable,
interoperable and extensible. Feel free to open a PR to create a document in the
`/proposals/` directory. Eventually we hope to move these to a repo that serves
this purpose.

## Community

- **Discord**
  [](https://discord.gg/NP5vbPeUFp) -
  Most discussion outside of GitHub happens on the GraphQL
  [Discord Server](https://discord.gg/NP5vbPeUFp)
- **Twitter** - [@GraphiQL](https://twitter.com/@GraphiQL) and
  [#GraphiQL](https://twitter.com/hashtag/GraphiQL)
- **GitHub** - Create feature requests, discussions issues and bugs above
- **Working Group** - Yes, you're invited! Monthly planning/decision making
  meetings, and working sessions every two weeks on zoom!
  [Learn more.](working-group#readme)

---

## File: docs/security/2021-introspection-schema-xss.md

- [1. GraphiQL introspection schema template injection attack: Advisory Statement](#1-graphiql-introspection-schema-template-injection-attack-advisory-statement)
  - [1.1. Impact](#11-impact)
  - [1.2. Scope](#12-scope)
  - [1.3. Patches](#13-patches)
  - [1.3.1 CDN bundle implementations may be automatically patched](#131-cdn-bundle-implementations-may-be-automatically-patched)
  - [1.4. Workarounds for Older Versions](#14-workarounds-for-older-versions)
  - [1.5. How to Re-create the Exploit](#15-how-to-re-create-the-exploit)
  - [1.6. Credit](#16-credit)
  - [1.7. References](#17-references)
  - [1.8. For more information](#18-for-more-information)
- [2. More Details on the Vulnerability](#2-more-details-on-the-vulnerability)
- [3. Compromised introspection Schema Example](#3-compromised-introspection-schema-example)

## 1. GraphiQL introspection schema template injection attack: Advisory Statement

This is a security advisory for an XSS vulnerability in `graphiql`.

A similar vulnerability affects `graphql-playground`, a fork of `graphiql`.
There is a corresponding `graphql-playground`
[advisory](https://github.com/graphql/graphql-playground/security/advisories/GHSA-59r9-6jp6-jcm7)
and
[Apollo Server advisory](https://github.com/apollographql/apollo-server/security/advisories/GHSA-qm7x-rc44-rrqw).

### 1.1. Impact

All versions of `graphiql` older than
[`graphiql@1.4.7`](https://github.com/graphql/graphiql/releases/tag/v1.4.7) are
vulnerable to compromised HTTP schema introspection responses or `schema` prop
values with malicious GraphQL type names, exposing a dynamic XSS attack surface
that can allow code injection on operation autocomplete.

In order for the attack to take place, the user must load a vulnerable schema in
`graphiql`. There are a number of ways that can occur.

By default, the schema URL is _not_ attacker-controllable in `graphiql` or in
its suggested implementations or examples, leaving only very complex attack
vectors.

If a custom implementation of `graphiql`'s `fetcher` allows the schema URL to be
set dynamically, such as a URL query parameter like `?endpoint=` in
`graphql-playground`, or a database provided value, then this custom `graphiql`
implementation is _vulnerable to phishing attacks_, and thus much more readily
available, low or no privilege level xss attacks. The URLs could look like any
generic looking graphql schema URL.

Because this exposes an XSS attack surface, it would be possible for a threat
actor to exfiltrate user credentials, data, etc. using arbitrary malicious
scripts, without it being known to the user.

### 1.2. Scope

This advisory describes the impact on the `graphiql` package. The vulnerability
also affects other projects forked from `graphiql` such as
[`graphql-playground`](https://github.com/graphql/graphql-playground/security/advisories/GHSA-59r9-6jp6-jcm7)
and the `graphql-playground` fork distributed by Apollo Server. The impact is
more severe in the `graphql-playground` implementations; see the
[`graphql-playground` advisory](https://github.com/graphql/graphql-playground/security/advisories/GHSA-59r9-6jp6-jcm7)
and
[Apollo Server advisory](https://github.com/apollographql/apollo-server/security/advisories/GHSA-qm7x-rc44-rrqw)
for details.

This vulnerability does not impact `codemirror-graphql`, `monaco-graphql` or
other dependents, as it exists in `onHasCompletion.ts` in `graphiql`. It does
impact all forks of `graphiql`, and every released version of `graphiql`.

It should be noted that desktop clients such as Altair, Insomnia, Postwoman, do
not appear to be impacted by this.

### 1.3. Patches

`graphiql@1.4.7` addresses this issue via defense in depth.

- **HTML-escaping text** that should be treated as text rather than HTML. In
  most of the app, this happens automatically because React escapes all
  interpolated text by default. However, one vulnerable component uses the
  unsafe `innerHTML` API and interpolated type names directly into HTML. We now
  properly escape that type name, which fixes the known vulnerability.

- **Validates the schema** upon receiving the introspection response or schema
  changes. Schemas with names that violate the GraphQL spec will no longer be
  loaded. (This includes preventing the Doc Explorer from loading.) This change
  is also sufficient to fix the known vulnerability. You can disable this
  validation by setting `dangerouslyAssumeSchemaIsValid={true}`, which means you
  are relying only on escaping values to protect you from this attack.

- **Ensuring that user-generated HTML is safe**. Schemas can contain Markdown in
  `description` and `deprecationReason` fields, and the web app renders them to
  HTML using the `markdown-it` library. As part of the development of
  `graphiql@1.4.7`, we verified that our use of `markdown-it` prevents the
  inclusion of arbitrary HTML. We use `markdown-it` without setting
  `html: true`, so we are comfortable relying on
  [`markdown-it`'s HTML escaping](https://github.com/markdown-it/markdown-it/blob/master/docs/security.md)
  here. We considered running a second level of sanitization over all rendered
  Markdown using a library such as `dompurify` but believe that is unnecessary
  as `markdown-it`'s sanitization appears to be adequate. `graphiql@1.4.7` does
  update to the latest version of `markdown-it` (v12, from v10) so that any
  security fixes in v11 and v12 will take effect.

### 1.3.1 CDN bundle implementations may be automatically patched

Note that if your implementation is depending on a CDN version of `graphiql`,
and is pointed to the `latest` tag (usually the default for most cdns if no
version is specified) then this issue is already mitigated, in case you were
vulnerable to it before.

### 1.4. Workarounds for Older Versions

If you cannot use `graphiql@1.4.7` or later

- Always use a static URL to a trusted server that is serving a trusted GraphQL
  schema.

- If you have a custom implementation that allows using user-provided schema
  URLs via a query parameter, database value, etc, you must either disable this
  customization, or only allow trusted URLs.

### 1.5. How to Re-create the Exploit

You can see an example on
[codesandbox](https://codesandbox.io/s/graphiql-xss-exploit-gr22f?file=/src/App.js).
These are both fixed to the last `graphiql` release `1.4.6` which is the last
vulnerable release; however it would work with any previous release of
`graphiql`.

Both of these examples are meant to demonstrate the phishing attack surface, so
they are customized to accept a `url` parameter. To demonstrate the phishing
attack, add `?url=https://graphql-xss-schema.netlify.app/graphql` to the
in-codesandbox browser.

Erase the contents of the given query and type `{u`. You will see an alert
window open, showing that attacker-controlled code was executed.

Note that when React is in development mode, a validation exception is thrown
visibly; however that exception is usually buried in the browser console in a
production build of `graphiql`. This validation exception comes from
`getDiagnostics`, which invokes `graphql` `validate()` which in turn will
`assertValidSchema()`, as `apollo-server-core` does on executing each operation.
This validation does not prevent the exploit from being successful.

Note that something like the `url` parameter is not required for the attack to
happen if `graphiql`'s `fetcher` is configured in a different way to communicate
with a compromised GraphQL server.

### 1.6. Credit

This vulnerability was discovered by [@Ry0taK](https://github.com/Ry0taK), thank
you! :1st_place_medal:

Others who contributed:

- [@imolorhe](https://github.com/imolorhe)
- [@glasser](https://github.com/glasser)
- [@divyenduz](https://github.com/divyenduz)
- [@dotansimha](https://github.com/dotansimha)
- [@acao](https://github.com/acao)
- [@benjie](https://github.com/benjie) and many others who provided morale
  support

### 1.7. References

**The vulnerability has always been present**

[In the first commit](https://github.com/graphql/graphiql/commit/b9dec272d89d9c590727fd10d62e4a47e0317fc7#diff-855b77f6310b7e4fb1bcac779cd945092ed49fd759f4684ea391b45101166437R87)

[And later moved to onHasCompletion.js in 2016](https://github.com/graphql/graphiql/commit/6701b0b626e43800e32413590a295e5c1e3d5419#diff-d45eb76aebcffd27d3a123214487116fa95e0b5a11d70a94a0ce3033ce09f879R110)
(now `.ts` after the typescript migration)

### 1.8. For more information

If you have any questions or comments about this advisory:

- Open an issue in
  [graphiql repo](https://github.com/graphql/graphiql/new/issues)

## 2. More Details on the Vulnerability

This section provides more details in addition to the advisory.

An installation of the GraphiQL web app is vulnerable if two conditions are met:

- The web app trusts information from its corresponding GraphQL server by
  interpolating information such as GraphQL type names directly into HTML
  instead of appropriately escaping or sanitizing the information.
- The victim can load the web app in a way where it speaks to a GraphQL server
  controlled by the attacker.

All versions of `graphiql` prior to 1.4.7 inappropriately trust type names
provided by the GraphQL server. They additionally rely on XSS filtering in the
`markdown-it` package to try to protect themselves from XSS attacks in GraphQL
descriptions and deprecation reasons.

By default, `graphiql` does _not_ allow the attacker to control what GraphQL
server it speaks to. Therefore, many installations of `graphiql` are not
affected by this advisory. Installations are only affected if the `fetcher`
argument provided to GraphiQL allows arbitrary customization of the GraphQL
endpoint (eg, reading a GraphQL URL from an URL parameter), or if the attacker
has another way of affecting the introspection schema returned by the GraphQL
server. (Note that `graphql-playground`, a project which started as a fork of
`graphiql`, does this sort of URL parsing by default, so `graphql-playground`
installations _are_ affected by a corresponding vulnerability in their default
configuration.)

One example of "another way of affecting the introspection schema" would be if
you served `graphiql` as part of a PAAS platform that allows users to define
their own GraphQL schemas. In this case, even though the `graphiql` installation
might be hard-wired to a single GraphQL endpoint, the attacker has control over
that GraphQL endpoint and could use it to inject scripts into `graphiql`. In
this case, your `graphiql` installation could be vulnerable if it responds to
introspection requests without first validating its schema. GraphQL servers can
prevent this by refusing to execute operations (including introspection
operations) on invalid schemas; any server built with `graphql-js` properly
validates its schema prior to execution.

## 3. Compromised introspection Schema Example

You can view the code for the exploited schema
[on codesandbox](https://codesandbox.io/s/graphql-xss-compromised-schema-3wdq7?file=/src/bad-schema.js)
or [in the repository](../../packages/graphiql/test/bad-schema.js)

As you can see, the introspection schema must contain items with a compromised
`name` value. this could be fields, input object names, enum names, variable
names, etc any graphql
[NamedType](https://github.com/graphql/graphql-spec/blob/main/spec/Section%202%20--%20Language.md#type-references)
in the schema with it's name rendered in the autocomplete list.

```json
{
  "kind": "OBJECT",
  "name": "",
  "description": null,
  "fields": [
    {
      "name": "name",
      "description": null,
      "args": [],
      "type": {
        "kind": "NON_NULL",
        "name": null,
        "ofType": {
          "kind": "SCALAR",
          "name": "String",
          "ofType": null
        }
      },
      "isDeprecated": false,
      "deprecationReason": null
    }
  ],
  "inputFields": null,
  "interfaces": [],
  "enumValues": null,
  "possibleTypes": null
}
```

---

## File: docs/migration/graphiql-2.0.0.md

# Upgrading `graphiql` from `1.x` to `2.0.0`

Hello GraphiQL user and thanks for upgrading!

This migration guide walks you through all changes that come with
`graphiql@2.0.0`, in particular the breaking ones, and will show you how to
upgrade your `1.x` implementation.

> If you encounter any issues while upgrading that are not covered in here,
> please open an issue or PR on this repo and we will extend this guide.

## Design refresh including dark theme

Arguably the biggest change in `graphiql@2` is the new design of the UI. It has
been reworked from scratch to look more modern while keeping its simplistic look
and feel. We also finally added a built-in dark theme. Theme selection is based
on system defaults and can be changed in the new settings dialog (available by
clicking on the gear icon at the bottom of the sidebar on the left of the
screen).

Starting with `graphiql@2`, the only officially supported way of customizing the
CSS that make up the looks of GraphiQL is by overriding the design tokens
defined using CSS variables. In particular, changes to class names are no longer
considered breaking changes. If you use class-name based selectors to change
styles your overrides might break with minor or patch version bumps.

A list of all CSS variables that can be customized can be found in the
[`root.css`](../../packages/graphiql-react/src/style/root.css) file of the
`@graphiql/react` package. The variables for colors use a list of values that
can be passed into the
[`hsl`](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl)
function in CSS that defines colors by hue, saturation and lightness.

## Changes to `GraphiQL` component props

A couple of props of the `GraphiQL` have undergone breaking changes:

- The props `defaultVariableEditorOpen` and `defaultSecondaryEditorOpen` have
  been merged into one prop `defaultEditorToolsVisibility`. The default behavior
  if this prop is not passed is that the editor tools are shown if at least one
  of the secondary editors has contents. You can pass the following values to
  the prop:
  - Passing `false` hides the editor tools.
  - Passing `true` shows the editor tools.
  - Passing `"variables"` explicitly shows the variables editor.
  - Passing `"headers"` explicitly shows the headers editor.
- The props `docExplorerOpen`, `onToggleDocs` and `onToggleHistory` have been
  removed. They are replaced by the more generic props `visiblePlugin` (for
  controlling which plugin is visible) and `onTogglePluginVisibility` (which is
  called each time the visibility of any plugin changes).
- The `headerEditorEnabled` prop has been renamed to `isHeadersEditorEnabled`.
- The `ResultsTooltip` prop has been renamed to `responseTooltip`.

### Tabs enabled by default

Tabs were supported opt-in starting with `@graphiql@1.8`. With `graphiql@2` tabs
are now always enabled. The `tabs` prop (which previously toggled if tabs were
enabled or not) has therefore been replaced with a prop `onTabChange`. If you
used the `tabs` prop before to pass this function you can change your
implementation like so:

```diff
<GraphiQL
-  tabs={{ onTabChange: (tabState) => {/* do something */} }}
+  onTabChange={(tabState) => {/* do something */}}
/>
```

As long as only one session is open, the tab bar above the editors is hidden. A
plus icon next to the logo on the top right allows the user to open more tabs.
With at least two tabs opened, the tab bar appears above the editors.

## Removed package exports

All React components apart from the `GraphiQL` component have been moved to the
`@graphiql/react` package. That's why we removed most of the exports with
`graphiql@2`. Here is a list of all exported components and functions that have
been removed and where you can find them now:

- `QueryEditor`, `VariableEditor` and `DocExplorer`: Now exported from
  `@graphiql/react` under the same names
  - Note that the `schema` prop of the `DocExplorer` no longer exists, the
    component now uses the schema provided by the `ExplorerContext`.
- `ToolbarMenu`: Now exported from `@graphiql/react` as `ToolbarMenu`
- `ToolbarMenuItem`: Now exported from `@graphiql/react` as `ToolbarMenu.Item`
- `ToolbarSelect`: Now exported from `@graphiql/react` as `ToolbarListbox`
- `ToolbarSelectOption`: Now exported from `@graphiql/react` as
  `ToolbarListbox.Option`
- `onHasCompletion`: This function is only meant to be used internally, it is no
  longer being exported
- `fillLeafs`, `getSelectedOperationName` and `mergeAst`: Now exported from
  `@graphiql/toolkit` under the same names
- types `Fetcher`, `FetcherOpts`, `FetcherParams`, `FetcherResult`,
  `FetcherReturnType`, `Observable`, `Storage` and `SyncFetcherResult`: Exported
  from `@graphiql/toolkit` under the same names (previously just re-exported by
  `graphiql`)

## `GraphiQL` is now a function component

The `GraphiQL` component in `graphiql@1.x` was a class component. That allowed
easy access to its props, state and methods by attaching a ref to it like so:

```tsx
import { createGraphiQLFetcher } from '@graphiql/toolkit';
import { GraphiQL } from 'graphiql';
import { Component } from 'react';

const fetcher = createGraphiQLFetcher({ url: 'https://my.endpoint' });

class MyComponent extends Component {
  _graphiql: GraphiQL;

  componentDidMount() {
    const query = this._graphiql.getQueryEditor().getValue();
  }

  render() {
    return <GraphiQL ref={r => (this._graphiql = r)} fetcher={fetcher} />;
  }
}
```

With `graphiql@2` we refactored the codebase to more "modern" React. This also
meant replacing all class components with function components. The code above no
longer works in `graphiql@2` as attaching refs to function components is not
possible in React.

All logic and state management now lives in multiple React contexts, provided by
the `@graphiql/react` package. The `GraphiQL` component is now basically
combining two other components, both of which are also exported by the package.

- `GraphiQLProvider` (originally coming from `@graphiql/react`) will render all
  context providers and takes care of state management
- `GraphiQLInterface` is defined in the `graphiql` package and renders the UI

If you want to read or modify GraphiQL state from your custom implementation you
need to render both the above components separately as the hooks for consuming
the context values only work in components that are rendered inside the provider
component.

With all that, the example above can be refactored a such:

```jsx
import { useEditorContext } from '@graphiql/react';
import { createGraphiQLFetcher } from '@graphiql/toolkit';
import { GraphiQLInterface, GraphiQLProvider } from 'graphiql';
import { useEffect } from 'react';

const fetcher = createGraphiQLFetcher({ url: 'https://my.endpoint' });

function MyComponent() {
  return (
    <GraphiQLProvider fetcher={fetcher}>
      
    </GraphiQLProvider>
  );
}

function InsideContext() {
  // Calling this hook would not work in `MyComponent` (it would return `null`)
  const { queryEditor } = useEditorContext();

  useEffect(() => {
    const query = queryEditor.getValue();
  }, [queryEditor]);

  return <GraphiQLInterface />;
}
```

Here is a list of all public class methods that existed in `graphiql@1` and its
replacement in `graphiql@2`. All the contexts mentioned below can be accessed
using a hook exported by `@graphiql/react`.

- `getQueryEditor`: Use the `queryEditor` property from the `EditorContext`.
- `getVariableEditor`: Use the `variableEditor` property from the
  `EditorContext`.
- `getHeaderEditor`: Use the `headerEditor` property from the `EditorContext`.
- `refresh`: Calling this method should no longer be necessary, all editors will
  refresh automatically after resizing. If you really need to refresh manually
  you have to call the `refresh` method on all editor instances individually.
- `autoCompleteLeafs`: Use the `useAutoCompleteLeafs` hook provided by
  `@graphiql/react` that returns this function.

There are a couple more class methods that were intended to be private and were
already removed starting in `graphiql@1.9.0`. Since they were not actually
marked with `private`, here's an extension to the above list for these methods:

- `handleClickReference`: This was a callback method triggered when clicking on
  a type or field. It would open the doc explorer for the clicked reference. If
  you want to manually mimic this behavior you can use the `push` method from
  the `ExplorerContext` to add an item to the navigation stack of the doc
  explorer, and you can use the `setVisiblePlugin` method of the `PluginContext`
  (use the `usePluginContext()` hook to access this) to show the doc explorer
  plugin (by passing the `DOC_EXPLORER_PLUGIN` object provided by
  `@graphiql/react`).
- `handleRunQuery`: To execute a query, use the `run` method of the
  `ExecutionContext`. If you want to explicitly set an operation name, call the
  `setOperationName` method of the `EditorContext` provider before that (passing
  in the operation name string as argument).
- `handleEditorRunQuery`: Use the `run` method of the `ExecutionContext`.
- `handleStopQuery`: Use the `stop` method from the `ExecutionContext`.
- `handlePrettifyQuery`: Use the `usePrettifyEditors` hook provided by
  `@graphiql/react` that returns this function.
- `handleMergeQuery`: Use the `useMergeQuery` hook provided by `@graphiql/react`
  that returns this function.
- `handleCopyQuery`: Use the `useCopyQuery` hook provided by `@graphiql/react`
  that returns this function.
- `handleToggleDocs` and `handleToggleHistory`: Use the `setVisiblePlugin`
  method of the `PluginContext`.

Some class methods were callbacks to modify state which are not intended to be
called manually. All these methods don't have a successor: `handleEditQuery`,
`handleEditVariables`, `handleEditHeaders`, `handleEditOperationName`,
`handleSelectHistoryQuery`, `handleResetResize` and
`handleHintInformationRender`

### Static properties have been removed

In `graphiql@1.x` the `GraphiQL` component included a bunch of static properties
that exposed utility functions and other components. Most of these have been
removed in `graphiql@2` since the components and functions have been moved to
the `@graphiql/react` and `@graphiql/toolkit` packages.

The properties that remain on the `GraphiQL` function component are
`GraphiQL.Logo`, `GraphiQL.Toolbar` and `GraphiQL.Footer`. All three are React
components that can be passed as children to the `GraphiQL` components and
override certain parts of the UI:

- `GraphiQL.Logo`: Overrides the "logo" at the top right of the screen. By
  default, it contains the text "Graph*i*QL".
- `GraphiQL.Toolbar`: Overrides the toolbar next to the operation editor. By
  default, if contains buttons for prettifying the current editor contents,
  merging fragment definitions into the operation definition and copying the
  contents of the operation editor to the clipboard. Note that the default buttons
  will not be shown when passing this component as child to `GraphiQL`, instead
  it will show the children you pass to `GraphiQL.Toolbar`. The execute button
  will always be shown. If you want to keep the default buttons and add
  additional buttons you can use the `toolbar` prop.
- `GraphiQL.Footer`: Adds a section below the response editor. By default, this
  won't show up in the UI.

Here is a list of all the static properties that have been removed and their
replacements:

- `GraphiQL.formatResult` and `GraphiQL.formatError`: Replaced by equally named
  functions from `@graphiql/toolkit`
- `GraphiQL.QueryEditor`, `GraphiQL.VariableEditor` and `GraphiQL.HeaderEditor`:
  Replaced by equally named components from `@graphiql/react`
- `GraphiQL.ResultViewer`: Replaced by the `ResponseEditor` component from
  `@graphiql/react`
- `GraphiQL.Button`: Replaced by the `ToolbarButton` component from
  `@graphiql/react`
- `GraphiQL.ToolbarButton`: This exposed the same component as
  `GraphiQL.Button`.
- `GraphiQL.Menu`: Replaced by the `ToolbarMenu` component from
  `@graphiql/react`
- `GraphiQL.MenuItem`: Replaced by the `ToolbarMenu.Item` component from
  `@graphiql/react`
- `GraphiQL.Group`: Grouping multiple buttons side-by-side is not provided
  out-of-the box anymore in the new GraphiQL UI. If you want to implement a
  similar feature in the new vertical toolbar you can do so by adding your own
  styles for your custom toolbar elements. Example:

  ```jsx
  import { createGraphiQLFetcher } from '@graphiql/toolkit';
  import { GraphiQL } from 'graphiql';

  const fetcher = createGraphiQLFetcher({ url: 'https://my.endpoint' });

  function MyComponent() {
    return (
      <GraphiQL fetcher={fetcher}>
        <GraphiQL.Toolbar>
          {/* Add custom styles for your buttons using the given class */}
          
            1
            2
            3
          
        </GraphiQL.Toolbar>
      </GraphiQL>
    );
  }
  ```

### `window.g` has been removed

In `graphiql@1.x` the `GraphiQL` class component stored a reference to itself on
a global property named `g`. This property has been removed as refs don't exist
for function components. (Also, the property was only intended for internal use
like testing in the first place.)

---

## File: docs/migration/graphiql-4.0.0.md

# Upgrading `graphiql` from `3.x` to `4.0.0`

---

## `graphiql`

- Dropped support for **React 16/17**, added support for **React 19**
- Dropped **CommonJS** build output – now **ESM only**
- Improved UI of tabs
  - Changed tabs behavior – tabs are always visible (even if only one)
  - Updated tabs tooltip usage – now use HTML `title` attribute
- Removed **default export**
- Removed `disableTabs` option
- Improved Markdown handling – single newlines are ignored
- Added `onPrettifyQuery` callback for custom formatting
- ⚠️ Deprecate **UMD CDN build `index.umd.js`**
- Changed **CDN paths** and **style import**

> [!WARNING]
>
> ⚠️ **`index.umd.js` is deprecated**. Switch to the [ESM CDN example](../../examples/graphiql-cdn/index.html).

### UMD CDN path changes

```diff
-https://unpkg.com/graphiql/graphiql.js
-https://unpkg.com/graphiql/graphiql.min.js
+https://unpkg.com/graphiql/dist/index.umd.js  // ⚠️ deprecated

-https://unpkg.com/graphiql/graphiql.css
-https://unpkg.com/graphiql/graphiql.min.css
+https://unpkg.com/graphiql/dist/style.css
```

### Default export removed

```diff
-import GraphiQL from 'graphiql'
+import { GraphiQL } from 'graphiql'
```

### Style import changed

```diff
-import 'graphiql/graphiql.css'
+import 'graphiql/style.css'
```

### Toolbar API migration

#### `toolbar.additionalContent` → `<GraphiQL.Toolbar>`

**Before:**

```tsx
<GraphiQL toolbar={{ additionalContent: My button }} />
```

**After:**

```jsx
<GraphiQL>
  <GraphiQL.Toolbar>
    {({ merge, prettify, copy }) => (
      <>
        {prettify}
        {merge}
        {copy}
        My button
      </>
    )}
  </GraphiQL.Toolbar>
</GraphiQL>
```

---

#### `toolbar.additionalComponent` → `<GraphiQL.Toolbar>`

**Before:**

```jsx
<GraphiQL
  toolbar={{
    additionalComponent: function MyComponentWithAccessToContext() {
      return My button;
    },
  }}
/>
```

**After:**

```jsx
<GraphiQL>
  <GraphiQL.Toolbar>
    {({ merge, prettify, copy }) => (
      <>
        {prettify}
        {merge}
        {copy}
        <MyComponentWithAccessToContext />
      </>
    )}
  </GraphiQL.Toolbar>
</GraphiQL>
```

---

#### Customizing default toolbar buttons

You can reorder or remove default toolbar buttons:

```tsx
<GraphiQL>
  <GraphiQL.Toolbar>
    {({ prettify, copy }) => (
      <>
        {copy} {/* Move copy button to the top */}
        {prettify} {/* Omit merge button */}
      </>
    )}
  </GraphiQL.Toolbar>
</GraphiQL>
```

---

## `@graphiql/react`

- Dropped support for **React 16/17**, added support for **React 19**
- Dropped **CommonJS** build output
- Improved UI of tabs
- Updated dependencies: `@radix-ui` and `@headlessui/react`
- Added `onPrettifyQuery` callback for custom formatting
- Improved Markdown handling (ignores single newlines)
- Style import changed:
  ```diff
  -import '@graphiql/react/dist/style.css'
  +import '@graphiql/react/style.css'
  ```

---

## `@graphiql/plugin-code-exporter`

- Dropped support for **React 16/17**, added support for **React 19**
- Dropped **CommonJS** build output
- Updated ESM-based CDN example:
  [code-exporter ESM CDN example](../../packages/graphiql-plugin-code-exporter/example/index.html)
- ⚠️ UMD build deprecated – migrate to ESM-based CDN
- Style import changed:
  ```diff
  -import '@graphiql/plugin-code-exporter/dist/style.css'
  +import '@graphiql/plugin-code-exporter/style.css'
  ```

---

## `@graphiql/plugin-explorer`

- Dropped support for **React 16/17**, added support for **React 19**
- Dropped **CommonJS** build output
- Improved styles for the explorer UI
- Updated ESM-based CDN example:
  [explorer ESM CDN example](../../examples/graphiql-cdn/index.html)
- ⚠️ UMD build deprecated – migrate to ESM-based CDN
- Style import changed:
  ```diff
  -import '@graphiql/plugin-explorer/dist/style.css'
  +import '@graphiql/plugin-explorer/style.css'
  ```

---

## File: examples/monaco-graphql-webpack/README.md

A simple example of `monaco-graphql` using webpack 4

[live demo](https://monaco-graphql.netlify.com) of the monaco webpack example

### Setup

`yarn` and `yarn start` from this folder to start webpack dev server

### JS only

If you want to learn how to bundle `monaco-graphql` using webpack without
typescript, these steps will help:

1. rename .ts files to .js
1. rename .ts to .js in webpack.config.js
1. remove fork ts checker plugin from webpack.config.js
1. remove typescript annotations from the renamed files

---

## File: examples/monaco-graphql-react-vite/README.md

# Monaco-GraphQL React Vite Example

## Getting Started

This is an extremely naive & minimalist implementation of `monaco-graphql` with
`react` using `vite` as a bundler.

This workspace could be used to help us prototype components & hooks for
`@graphiql/react`

[Here is a StackBlitz demo of this example](https://stackblitz.com/edit/monaco-graphql-react-vite?file=src/App.tsx)

## Setup

1. In monorepo root directory run `yarn` and `yarn build`.
1. In this directory run `yarn dev`.

---

## File: examples/monaco-graphql-nextjs/README.md

# Monaco GraphQL Next.js Example

## Getting Started

This is a working example of `monaco-editor` and `monaco-graphql` using
Next.js 15 with Turbopack.

It shows how to use the latest monaco-editor with next.js and a custom
webworker, without using `@monaco/react` or `monaco-editor-react`'s approach of
cdn (AMD) bundles. These approaches avoid using ESM `monaco-editor` or web
workers, which prevents introducing custom web workers like with
`monaco-graphql`.

For lazy loading, we use `next/dynamic` with `{ssr: false}`, but any
similar client-side-only loading (with or without dynamic import) should be
fine. For more information on loading `monaco-editor` in esm contexts, you can
[read their docs](https://github.com/microsoft/monaco-editor/blob/main/docs/integrate-esm.md)

This work was sponsored by [Grafbase](https://grafbase.com)!

## Setup

1. In monorepo root directory run `yarn` and `yarn build`.
1. In this directory run `yarn dev`.

---

## File: examples/graphiql-webpack/README.md

## GraphiQL Webpack Example

This example demonstrates how to transpile your own custom ES6 GraphiQL
implementation with webpack and babel configuration.

It shows how to add plugins and even how to create a custom plugin.

There is also a no-config example with `create-react-app`:

[](https://codesandbox.io/s/graphiql-example-nhzvc)

It appears `create-react-app` supports all the language features we require.

### Setup

1. `yarn` and `yarn start` from this folder to start webpack dev server

---

## File: examples/graphiql-parcel/README.md

# GraphiQL Parcel Example

> [!WARNING]
>
> This example has been removed. You can find its last version [here](https://github.com/graphql/graphiql/tree/3b93d27f7568d93db5cd146157220b127eeea737/examples/graphiql-parcel).
> We recommend using the [GraphiQL Vite](../graphiql-vite) or [GraphiQL Next.js](../graphiql-nextjs) examples instead.

---

## File: examples/graphiql-create-react-app/README.md

# GraphiQL `create-react-app` Example

> [!WARNING]
>
> This example has been removed. You can find its last version [here](https://github.com/graphql/graphiql/tree/3b93d27f7568d93db5cd146157220b127eeea737/examples/graphiql-create-react-app).
> We recommend using the [GraphiQL Vite](../graphiql-vite) or [GraphiQL Next.js](../graphiql-nextjs) examples instead.