Skip to content

Instantly share code, notes, and snippets.

@olivermt
Created March 14, 2025 11:11
Show Gist options
  • Save olivermt/a5d0cc74ea987e83ef10f68b5b21891f to your computer and use it in GitHub Desktop.
Save olivermt/a5d0cc74ea987e83ef10f68b5b21891f to your computer and use it in GitHub Desktop.
defmodule YourAppWeb.GraphiQLController do
use YourAppWeb, :controller
def graphiql(conn, _params) do
graphiql =
Path.join([:code.priv_dir(:your_app_here), "graphiql", "graphiql.html"])
conn
|> put_resp_header("content-type", "text/html; charset=utf-8")
|> Plug.Conn.send_file(200, graphiql)
end
end
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex" />
<meta name="referrer" content="origin" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SafariDB GraphQL API</title>
<style>
body {
height: 100vh;
margin: 0;
overflow: hidden;
}
#splash {
color: #333;
display: flex;
flex-direction: column;
font-family: system, -apple-system, "San Francisco",
".SFNSDisplay-Regular", "Segoe UI", Segoe, "Segoe WP",
"Helvetica Neue", helvetica, "Lucida Grande", arial, sans-serif;
height: 100vh;
justify-content: center;
text-align: center;
}
</style>
<link rel="icon" href="favicon.ico" />
<link
type="text/css"
href="//unpkg.com/graphiql/graphiql.min.css"
rel="stylesheet"
/>
</head>
<body>
<div id="splash">Loading&hellip;</div>
<script src="//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js"></script>
<script src="//unpkg.com/graphiql/graphiql.min.js"></script>
<script>
// Parse the search string to get url parameters.
var search = window.location.search;
var parameters = {};
search
.substr(1)
.split("&")
.forEach(function (entry) {
var eq = entry.indexOf("=");
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] =
decodeURIComponent(entry.slice(eq + 1));
}
});
// if variables was provided, try to format it.
if (parameters.variables) {
try {
parameters.variables = JSON.stringify(
JSON.parse(parameters.variables),
null,
2
);
} catch (e) {
// Do nothing, we want to display the invalid JSON as a string, rather
// than present an error.
}
}
// When the query and variables string is edited, update the URL bar so
// that it can be easily shared
function onEditQuery(newQuery) {
parameters.query = newQuery;
updateURL();
}
function onEditVariables(newVariables) {
parameters.variables = newVariables;
updateURL();
}
function onEditOperationName(newOperationName) {
parameters.operationName = newOperationName;
updateURL();
}
function updateURL() {
var newSearch =
"?" +
Object.keys(parameters)
.filter(function (key) {
return Boolean(parameters[key]);
})
.map(function (key) {
return (
encodeURIComponent(key) +
"=" +
encodeURIComponent(parameters[key])
);
})
.join("&");
history.replaceState(null, null, newSearch);
}
function graphQLFetcher(graphQLParams) {
// This example expects a GraphQL server at the path /graphql.
// Change this to point wherever you host your GraphQL server.
return fetch("/api/v4/graphql", {
method: "post",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(graphQLParams),
})
.then(function (response) {
return response.text();
})
.then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
}
// Render <GraphiQL /> into the body.
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher,
query: parameters.query,
variables: parameters.variables,
operationName: parameters.operationName,
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName,
}),
document.body
);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment