Skip to content

fix(graphiql-react): preserve host when previewing image URLs#4332

Merged
trevor-scheer merged 1 commit into
graphql:mainfrom
vishwakt:fix/image-preview-absolute-url
Jun 6, 2026
Merged

fix(graphiql-react): preserve host when previewing image URLs#4332
trevor-scheer merged 1 commit into
graphql:mainfrom
vishwakt:fix/image-preview-absolute-url

Conversation

@vishwakt

@vishwakt vishwakt commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

In the response viewer, hovering an image URL shows an inline preview. The preview gets the hovered word from Monaco's getWordAtPosition, and Monaco's JSON word pattern treats : as a separator. So a full URL like https://example.com/img.png arrives as the protocol-relative //example.com/img.png.

pathToURL then stripped the leading character (path.slice(1)), turning //example.com/img.png into the host-relative /example.com/img.png, so the image was fetched from the current origin (https://<current-host>/example.com/img.png) instead of the real host.

The fix stops stripping that character. //host/path now resolves to the original host, and relative paths such as /images/foo.png still resolve against the current origin.

Closes #4101.

How to verify

  1. Run a query whose response contains a field with a full https:// image URL (for example a logo or avatar hosted on another domain).
  2. In the response pane, hover over the path part of that URL to trigger the image preview.
  • Before: the preview is broken, because it requests the image from the current host.
  • After: the preview loads, because it requests the image from the original host.

A unit test (image-preview.spec.ts) also covers this: pathToURL('//example.com/img.png') now resolves to host example.com rather than the current origin.

Credit

Thanks to @nastoychev for the report and for pinpointing pathToURL and the expected behavior.

The response viewer image preview gets the hovered word from Monaco's
getWordAtPosition. Monaco's JSON word pattern treats ':' as a separator, so a
full URL like https://example.com/img.png arrives as the protocol-relative
//example.com/img.png. pathToURL then stripped the leading character, turning
it into the host-relative /example.com/img.png and fetching the image from the
current origin instead of the real host.

Stop stripping the leading character so //host/path resolves to the original
host, while relative paths still resolve against the current origin.

Closes graphql#4101.
@changeset-bot

changeset-bot Bot commented Jun 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 078753f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@graphiql/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@trevor-scheer

Copy link
Copy Markdown
Contributor

Do you happen to have a live endpoint / query I can run that returns an image? If not I can spin one up but if you already tested and have one handy that'd be great. Thanks!

@vishwakt

vishwakt commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

Do you happen to have a live endpoint / query I can run that returns an image? If not I can spin one up but if you already tested and have one handy that'd be great. Thanks!

@trevor-scheer, Yes! The public Rick and Morty API works well for this:

Endpoint: https://rickandmortyapi.com/graphql

{
  characters(page: 1) {
    results { name image }
  }
}

The image field returns a full cross-origin URL

Before (image requested from the current host, so it fails to load):
graphiql-4332-before

After (loads from the original host):
graphiql-4332-after

@trevor-scheer

Copy link
Copy Markdown
Contributor

@vishwakt perfect, thanks!

@trevor-scheer trevor-scheer merged commit 61d138f into graphql:main Jun 6, 2026
13 checks passed
@github-actions github-actions Bot mentioned this pull request Jun 6, 2026
trevor-scheer pushed a commit that referenced this pull request Jun 6, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## codemirror-graphql@2.2.7

### Patch Changes

- Updated dependencies
[[`a526a10`](a526a10)]:
  - graphql-language-service@5.5.2
## @graphiql/react@0.37.6

### Patch Changes

- [#4332](#4332)
[`61d138f`](61d138f)
Thanks [@vishwakt](https://github.com/vishwakt)! - Fix image previews in
the response viewer fetching from the wrong host. Monaco splits the
hovered word on `:`, so a full URL like `https://example.com/img.png`
reaches the preview as the protocol-relative `//example.com/img.png`.
The preview stripped the leading character, turning that into the
host-relative `/example.com/img.png` and fetching it from the current
origin. The original host is now preserved.

- Updated dependencies
[[`a526a10`](a526a10)]:
  - graphql-language-service@5.5.2
## graphql-language-service@5.5.2

### Patch Changes

- [#4329](#4329)
[`a526a10`](a526a10)
Thanks [@vishwakt](https://github.com/vishwakt)! - Make the fields block
optional when parsing object, interface, input, and enum type
definitions (and their extensions) in the online parser. Per the GraphQL
spec these blocks are optional, so spec-valid SDL such as `extend type
Foo @onType` or `type Foo @onType` (directives only, no body) no longer
reports `invalidchar` during syntax highlighting.
## graphql-language-service-server@2.14.10

### Patch Changes

- [#4328](#4328)
[`d6b71ce`](d6b71ce)
Thanks [@vishwakt](https://github.com/vishwakt)! - Move
`debounce-promise` from `devDependencies` to `dependencies`. It is
imported at runtime in `MessageProcessor.ts`, so it must be a regular
dependency. Previously the package only resolved it via hoisting, which
fails under strict installs (e.g. `pnpm` v11), causing `graphql-lsp` to
crash with `Cannot find module 'debounce-promise'`.

- [#4331](#4331)
[`e1077b9`](e1077b9)
Thanks [@vishwakt](https://github.com/vishwakt)! - Import `Logger` from
`vscode-jsonrpc` instead of `vscode-languageserver`. `Logger` is defined
in `vscode-jsonrpc` (a direct dependency) and only reached
`vscode-languageserver` through a transitive re-export, which `tsgo`
failed to resolve on CI (`Module '"vscode-languageserver"' has no
exported member 'Logger'`). Importing from the package that owns the
type avoids relying on that fragile re-export chain.

- Updated dependencies
[[`a526a10`](a526a10)]:
  - graphql-language-service@5.5.2
## vscode-graphql-execution@0.3.6

### Patch Changes

- [#4306](#4306)
[`7aefde8`](7aefde8)
Thanks [@dependabot](https://github.com/apps/dependabot)! - Bump `ws` to
8.20.1 to address
[GHSA-58qx-3vcg-4xpx](GHSA-58qx-3vcg-4xpx)
(uninitialized memory disclosure in `websocket.close()`).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GraphiQL] 5.2.0 – Image preview not loaded correctly

2 participants