Skip to content

feat: Apollo Sandbox Renderer instead of GraphiQL #3654

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/red-dingos-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-yoga/render-apollo-sandbox': patch
---

New renderer for Apollo Sandbox instead of GraphiQL
71 changes: 71 additions & 0 deletions packages/render-apollo-sandbox/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "@graphql-yoga/render-apollo-sandbox",
"version": "0.0.0",
"type": "module",
"repository": {
"type": "git",
"url": "https://github.com/dotansimha/graphql-yoga.git",
"directory": "packages/plugins/apollo-sandbox"
},
"author": "Arda TANRIKULU <[email protected]>",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
".": {
"require": {
"types": "./dist/typings/index.d.cts",
"default": "./dist/cjs/index.js"
},
"import": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
},
"default": {
"types": "./dist/typings/index.d.ts",
"default": "./dist/esm/index.js"
}
},
"./*": {
"require": {
"types": "./dist/typings/*.d.cts",
"default": "./dist/cjs/*.js"
},
"import": {
"types": "./dist/typings/*.d.ts",
"default": "./dist/esm/*.js"
},
"default": {
"types": "./dist/typings/*.d.ts",
"default": "./dist/esm/*.js"
}
},
"./package.json": "./package.json"
},
"typings": "dist/typings/index.d.ts",
"peerDependencies": {
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0",
"graphql-yoga": "workspace:^"
},
"dependencies": {
"tslib": "^2.5.0"
},
"devDependencies": {
"graphql": "16.10.0",
"graphql-yoga": "workspace:^"
},
"publishConfig": {
"directory": "dist",
"access": "public"
},
"sideEffects": false,
"buildOptions": {
"input": "./src/index.ts"
},
"typescript": {
"definition": "dist/typings/index.d.ts"
}
}
132 changes: 132 additions & 0 deletions packages/render-apollo-sandbox/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import type { GraphiQLOptions } from 'graphql-yoga';

export interface ApolloSandboxOptions {
/**
* The URL of the GraphQL endpoint that Sandbox introspects on initial load. Sandbox populates its pages using the schema obtained from this endpoint.
* The default value is `http://localhost:4000`.
* You should only pass non-production endpoints to Sandbox. Sandbox is powered by schema introspection, and we recommend [disabling introspection in production](https://www.apollographql.com/blog/graphql/security/why-you-should-disable-graphql-introspection-in-production/).
* To provide a "Sandbox-like" experience for production endpoints, we recommend using either a [public variant](https://www.apollographql.com/docs/graphos/platform/graph-management/variants#public-variants) or the [embedded Explorer](https://www.apollographql.com/docs/graphos/platform/explorer/embed).
*/
initialEndpoint?: string;
/**
* By default, the embedded Sandbox does not show the **Include cookies** toggle in its connection settings.Set `hideCookieToggle` to `false` to enable users of your embedded Sandbox instance to toggle the **Include cookies** setting.
*/
hideCookieToggle?: boolean;
/**
* By default, the embedded Sandbox has a URL input box that is editable by users.Set endpointIsEditable to false to prevent users of your embedded Sandbox instance from changing the endpoint URL.
*/
endpointIsEditable?: boolean;
/**
* You can set `includeCookies` to `true` if you instead want Sandbox to pass `{ credentials: 'include' }` for its requests.If you pass the `handleRequest` option, this option is ignored.Read more about the `fetch` API and credentials [here](https://developer.mozilla.org/en-US/docs/Web/API/fetch#credentials).This config option is deprecated in favor of using the connection settings cookie toggle in Sandbox and setting the default value via `initialState.includeCookies`.
*/
includeCookies?: boolean;
/**
* An object containing additional options related to the state of the embedded Sandbox on page load.
*/
initialState?: InitialState;
}

interface InitialState {
/**
* Set this value to `true` if you want Sandbox to pass `{ credentials: 'include' }` for its requests by default.If you set `hideCookieToggle` to `false`, users can override this default setting with the **Include cookies** toggle. (By default, the embedded Sandbox does not show the **Include cookies** toggle in its connection settings.)If you also pass the `handleRequest` option, this option is ignored.Read more about the `fetch` API and credentials [here](https://developer.mozilla.org/en-US/docs/Web/API/fetch#credentials).
*/
includeCookies?: boolean;
/**
* A URI-encoded operation to populate in Sandbox's editor on load.If you omit this, Sandbox initially loads an example query based on your schema.Example:
* ```js
* initialState: {
* document: `
* query ExampleQuery {
* books {
* title
* }
* }
* `
* }
* ```
*/
document?: string;
/**
* A URI-encoded, serialized object containing initial variable values to populate in Sandbox on load.If provided, these variables should apply to the initial query you provide for [`document`](https://www.apollographql.com/docs/apollo-sandbox#document).Example:
*
* ```js
* initialState: {
* variables: {
* userID: "abc123"
* },
* }
* ```
*/
variables?: string;
/**
* A URI-encoded, serialized object containing initial HTTP header values to populate in Sandbox on load.Example:
*
*
* ```js
* initialState: {
* headers: {
* authorization: "Bearer abc123";
* }
* }
* ```
*/
headers?: string;
/**
* The ID of a collection, paired with an operation ID to populate in Sandbox on load. You can find these values from a registered graph in Studio by clicking the **...** menu next to an operation in the Explorer of that graph and selecting **View operation details**.Example:
*
* ```js
* initialState: {
* collectionId: 'abc1234',
* operationId: 'xyz1234'
* }
* ```
*/
collectionId?: string;
operationId?: string;
/**
* If `true`, the embedded Sandbox periodically polls your `initialEndpoint` for schema updates.The default value is `true`.Example:
*
* ```js
* initialState: {
* pollForSchemaUpdates: false;
* }
* ```
*/
pollForSchemaUpdates?: boolean;
/**
* Headers that are applied by default to every operation executed by the embedded Sandbox. Users can turn off the application of these headers, but they can't modify their values.The embedded Sandbox always includes these headers in its introspection queries to your `initialEndpoint`.Example:
*
* ```js
* initialState: {
* sharedHeaders: {
* authorization: "Bearer abc123";
* }
* }
* ```
*/
sharedHeaders?: Record<string, string>;
}

export function renderApolloSandbox(sandboxOpts?: ApolloSandboxOptions) {
return function renderApolloSandbox(graphiqlOpts: GraphiQLOptions) {
const initialState: InitialState = {
document: graphiqlOpts.defaultQuery,
headers: graphiqlOpts.headers,
sharedHeaders: graphiqlOpts.additionalHeaders,
...sandboxOpts?.initialState,
};
const finalOpts: ApolloSandboxOptions = {
...sandboxOpts,
initialState,
};
return /* HTML */ `
<div style="width: 100%; height: 100%;" id="embedded-sandbox"></div>
<script src="https://embeddable-sandbox.cdn.apollographql.com/_latest/embeddable-sandbox.umd.production.min.js"></script>
<script>
const opts = ${JSON.stringify(finalOpts)};
opts.initialEndpoint ||= new URL(location.pathname, location.href).toString();
new window.EmbeddedSandbox(opts);
</script>
`;
};
}
22 changes: 18 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions website/src/pages/docs/features/graphiql.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,29 @@ will need to add some sources to your CSP configuration:
- `unpkg.com`: GraphiQL styles are loaded directly from its module bundle, next to its scripts.
- `img-src`:
- `raw.githubusercontent.com`: The Guild logo is loaded from github

## Apollo Sandbox (as alternative)

If you want to use [Apollo Sandbox](https://www.apollographql.com/docs/apollo-sandbox) in favor of
GraphiQL. You can install this package and use it;

```sh npm2yarn
npm i @graphql-yoga/render-apollo-sandbox
```

```ts filename="Use Apollo Sandbox"
import { createYoga } from 'graphql-yoga'
import { renderApolloSandbox } from '@graphql-yoga/render-apollo-sandbox'

// Pass Apollo Sandbox renderer instead of GraphiQL
const yoga = createYoga({
renderGraphiQL: renderApolloSandbox({
/**
* Options here
*/
})
})
```

About the options, see here:
[Apollo Sandbox Options](https://www.apollographql.com/docs/apollo-sandbox#options)
Loading