Major Changes
-
#4423
f45e26bThanks @trevor-scheer! -cnis no longer exported from@graphiql/react; importclsxdirectly. -
#4393
827da62Thanks @trevor-scheer! - Remove deprecated hooks:useEditorContext,useExecutionContext,usePluginContext,useSchemaContext,useTheme,useStorage,useStorageContext,usePrettifyEditors,useCopyQuery,useMergeQuery, the*Storealiases (in@graphiql/react);useExplorerContext(in@graphiql/plugin-doc-explorer); anduseHistoryContext(in@graphiql/plugin-history). Replacements were available since v5 — see the v6 migration guide for one-line replacements.
Minor Changes
-
#4359
ac56840Thanks @trevor-scheer! - New@graphiql/plugin-collectionsplugin for saving named operations into folder collections and reusing them later, default-installed in thegraphiqlmeta-package so a Collections rail icon appears out of the box (passing thepluginsprop opts out of the default set as before).- Collapsible tree UI with inline rename, hover-revealed row actions, and QRY/MUT/SUB pills (a
MIXpill when a saved document holds more than one operation). - Save the current operation with ⌘S/Ctrl+S or the tab-strip Save button. An operation opened from a collection stays linked, so re-saving updates it in place; otherwise a "Save to collection" dialog opens. Clicking a saved item opens it in a new tab.
- Reorder within and across collections by drag-and-drop or keyboard (focus a row's drag handle, Space to grab, arrow keys to move, Space to drop, Escape to cancel).
- Copy a raw query or Share an importable envelope from any row; collection headers expose Share. Paste or drop a collections export anywhere in the pane to merge it in, or import/export JSON from the dialog. Imports reconcile by stable id, so re-importing updates in place and never duplicates; a conflict dialog lets you apply incoming changes, keep yours, or review each, and merge never deletes.
- Pluggable persistence via the
storageoption (defaults tolocalStorage), plusreadOnly,allowImportExport, andallowReplacefor governed deployments.
To support this without the core depending on any specific plugin,
@graphiql/reactgains a save API:registerSaveHandler(handler)(⌘S and the Save button fan out to every registered handler plus theonSaveQueryprop, and the dirty-state affordance only appears when at least one is registered), theonSaveQuery(tab)prop withmarkTabSaved(tabId)for deferred saves, andGraphiQLPlugin.sessionActions, an always-mounted plugin slot for toolbar buttons, dialogs, or behavior registration. The dirty-state dot means "a saved operation has unsaved edits" and survives a reload, so a tab that was never saved reads clean. - Collapsible tree UI with inline rename, hover-revealed row actions, and QRY/MUT/SUB pills (a
-
#4277
d4f0268Thanks @trevor-scheer! - Add aKeycapHintprimitive for displaying inline keyboard shortcuts (e.g.⌘K,⌘⏎), available for general consumer use. It takes semantic modifier names via theMODIFIERconstant:MODIFIER.Metarenders as⌘on macOS andCtrlelsewhere;Ctrl/Alt/Shiftrender as Mac glyphs (⌃/⌥/⇧) on macOS and plain text on other platforms;Enterrenders as⏎everywhere. -
#4285
c25bfd5Thanks @trevor-scheer! - Add aMethodPillprimitive: a small colored pill labeling an operation as QRY (query), MUT (mutation), or SUB (subscription). -
#4352
f8a9445Thanks @trevor-scheer! - The active operation now follows the editor cursor. As you move the cursor between operations in a multi-operation document,operationNameupdates to the operation the cursor sits in, so the operation dropdown and operation-aware plugins all reflect where you are editing. PreviouslyoperationNameonly changed on run-at-cursor or via the operation dropdown.Two consequences if you embed GraphiQL: the
onEditOperationNamecallback now fires when the cursor crosses into a different named operation, and a tab containing multiple operations shows the active operation name with a+Ncount of the others. Pinning an operation with theoperationNameprop still overrides cursor tracking.The Run button now offers an operation picker: in a document with multiple named operations, a dropdown on the Run button lets you choose which operation to run, and the menu marks which operation is currently active. The active operation still follows the editor cursor by default.
-
#4284
1ce71e4Thanks @trevor-scheer! - Add aPanelHeaderprimitive for side panels. Renders a title, optional subtitle, and optional action-icon row. -
#4321
03535abThanks @trevor-scheer! - Add a response pane header with real status, elapsed time, and response size from the active transport, a copy button, and a JSON / Tree / Table view toggle (the selection is persisted and restored on reload).- Tree renders the response JSON as a collapsible tree with type-colored values; top-level nodes expand by default and deeper levels start collapsed.
- Table renders each list field as its own table captioned with its path (e.g.
test.person.friends); sibling and aliased lists each get a table, nested objects and arrays show as shorthand summaries, non-list responses show an empty state, and rows get a bottom divider.
-
#4282
a0fe11aThanks @trevor-scheer! - Add aSegmentedControlprimitive for selecting one option from a small set inline, used by the response view toggle and several settings controls. It is built on native radio inputs, so keyboard navigation (arrow keys, Home / End) and screen-reader semantics come from the browser and the group is a single tab stop. -
#4338
480afc1Thanks @trevor-scheer! - Add aSettingsDialogwith theme, density, font-size, and persist-headers controls, backed by a newuseGraphiQLSettings()hook that persists preferences tolocalStorageand applies them to the GraphiQL container viadata-*attributes. Density and font-size presets fill in concrete token values for the[data-density]and[data-font-size]blocks intokens.css; Monaco editor font size, the status bar, and UI icon sizes follow the active font-size preset. TheforcedThemeandshowPersistHeadersSettingsprops continue to work, withforcedThemehiding the theme control. -
#4333
093cb10Thanks @trevor-scheer! - Add a structuredTransportAPI alongside the existingFetcher.createTransport({...})performs the GraphQL request and returns aTransportResponsecarrying the real HTTP wire metadata (status, headers, timing, size) for queries, mutations, subscriptions, and incremental delivery, so the response pane can surface those values directly instead of fabricating them. That metadata is there even when the response body isn't valid JSON (an HTML error page from a proxy, a plain-text 401), so a broken response still shows its real status code instead of a generic error.<GraphiQL>accepts a newtransportprop, mutually exclusive withfetcherat the type level.Transports support GET, POST, and the HTTP
QUERYmethod per the GraphQL over HTTP spec. Passmethod/supportedMethodsto choose; GET encodes the query into the URL with no body,QUERYsends a JSON body but is safe and idempotent, and mutations are always sent over POST (or blocked when POST is unavailable).Transportexposesurl,method,supportedMethods, and an optionalsetMethod, and the top bar shows the active method and endpoint with an inline switcher that cycles through the supported methods. Every request, incremental delivery on or off, sendsapplication/graphql-response+jsonin itsacceptheader alongsideapplication/json, so spec-compliant servers don't fall back to legacy response semantics. Subscriptions require an explicitsubscriptionClientsatisfying a smallSubscriptionClientcontract: a single.subscribe(request, sink)method thatgraphql-wsandgraphql-sseclients meet directly. The low-levelsimpleHttpTransportandmultipartHttpTransportprimitives also accept an optionalmethod.TransportRequestcarriesextensionsfor GraphQL-over-HTTP extensions such as automatic persisted queries (encoded into the URL forGET, included in the JSON body forPOSTandQUERY), andsignal, anAbortSignalthat cancels an in-flight query or mutation. Stopping a running query or mutation aborts the request; stopping a subscription closes the underlying socket or SSE connection.TransportResponse.okreflects both layers: the HTTP status and the absence of top-level GraphQL errors, so a 401 or 500 is neverok: truejust because its body happens to parse as JSON with noerrors.Plugins can observe and transform traffic through
transport.onBeforeSend,transport.onResponse, andtransport.onError, available viauseGraphiQLPluginContext()(all three return a cleanup function; thetransportfield isundefinedunder the legacyfetcherpath, so guard with optional chaining).onErrorfires when a request fails outright, such as a network error, so plugins can react to failures the same way they observe successful responses.createGraphiQLFetcher, theFetchertype and its companions, and<GraphiQL fetcher={...}>are deprecated but continue to work unchanged. Consumers on the deprecated path see a one-time dismissible banner in the response pane pointing atdocs/migration/graphiql-6.0.0.mdrather than fabricated status/timing/size values. The CDN bundle exposesGraphiQL.createTransportandGraphiQL.createWsClientso script-tag consumers can adopt without a bundler. -
#4228 Thanks @trevor-scheer! - A ground-up visual redesign for v6. A new OKLCH-based design-token system brings first-class light and dark themes, driven by a
data-themeattribute on the GraphiQL container. The layout is rebuilt around a top bar (endpoint and Run action), a left activity rail for plugins, a resizable side panel, a slim status bar, a flattened editor workspace, and a Variables/Headers tab strip. Every built-in component and both Monaco editor themes are restyled to match, and the doc explorer and history panels are rebuilt on the new chrome.GraphQL syntax coloring is unified across the doc explorer, history, and query builder, with type names colored by category. The mapping is public API for retheming: the
--type-scalar,--type-enum,--type-input, and--type-compositeCSS tokens, plus thetypeCategoryhelper exported from@graphiql/react.Custom CSS that overrides GraphiQL's internal class names may need updating; only the CSS custom properties (design tokens) are supported theming API. The build now targets the
defaultsbrowserslist preset, which covers the modern browsers the OKLCH color system requires. See the migration guide atdocs/migration/graphiql-6.0.0.md. Refs #4219.
Patch Changes
-
#4409
0f96193Thanks @trevor-scheer! - History label edits can now be canceled with Escape, and focus returns to the row's edit button instead of dropping to the page.Dialoggains an optionalrestoreFocusRefprop for returning focus to a specific element on close. -
#4413
1919f6aThanks @trevor-scheer! - Add a global keyboard focus ring and fill in a few missing screen-reader labels. Every control now shows a clearly visible blue outline when focused with the keyboard, with enough contrast against the canvas in both light and dark themes. Decorative icons that sit next to a text label no longer announce a redundant name, the doc explorer search box shows a focus ring while typing, and the cancel button on a history label edit now has an accessible name. -
Updated dependencies [
26ae143,093cb10]:- @graphiql/toolkit@1.0.0-beta.0