diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md
index 6f5afa1f..80a88f3f 100644
--- a/juniper/CHANGELOG.md
+++ b/juniper/CHANGELOG.md
@@ -18,11 +18,14 @@ See [#419](https://github.com/graphql-rust/juniper/pull/419).
 - `SchemaType` is now public
   - This is helpful when using `context.getSchema()` inside of your field resolvers
 
+- Support subscriptions in GraphiQL
+
 See [#569](https://github.com/graphql-rust/juniper/pull/569).
 
 ## Breaking Changes
 
 - `juniper::graphiql` has moved to `juniper::http::graphiql`
+  - `juniper::http::graphiql::graphiql_source` now requies a second parameter for subscriptions
 
 - remove old `graphql_object!` macro, rename `object` proc macro to `graphql_object`
 
diff --git a/juniper/src/http/graphiql.rs b/juniper/src/http/graphiql.rs
index f79d091e..d1cd12ce 100644
--- a/juniper/src/http/graphiql.rs
+++ b/juniper/src/http/graphiql.rs
@@ -1,7 +1,23 @@
 //! Utility module to generate a GraphiQL interface
 
 /// Generate the HTML source to show a GraphiQL interface
-pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
+///
+/// The subscriptions endpoint URL can optionally be provided. For example:
+///
+/// ```
+/// # use juniper::http::graphiql::graphiql_source;
+/// let graphiql = graphiql_source("/graphql", Some("ws://localhost:8080/subscriptions"));
+/// ```
+pub fn graphiql_source(
+    graphql_endpoint_url: &str,
+    subscriptions_endpoint_url: Option<&str>,
+) -> String {
+    let subscriptions_endpoint = if let Some(sub_url) = subscriptions_endpoint_url {
+        sub_url
+    } else {
+        ""
+    };
+
     let stylesheet_source = r#"
     <style>
         html, body, #app {
@@ -14,6 +30,10 @@ pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
     "#;
     let fetcher_source = r#"
     <script>
+        if (usingSubscriptions) {
+            var subscriptionsClient = new window.SubscriptionsTransportWs.SubscriptionClient(GRAPHQL_SUBSCRIPTIONS_URL, { reconnect: true });
+        }
+
         function graphQLFetcher(params) {
             return fetch(GRAPHQL_URL, {
                 method: 'post',
@@ -33,9 +53,12 @@ pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
                 }
             });
         }
+
+        var fetcher = usingSubscriptions ? window.GraphiQLSubscriptionsFetcher.graphQLFetcher(subscriptionsClient, graphQLFetcher) : graphQLFetcher;
+
         ReactDOM.render(
             React.createElement(GraphiQL, {
-                fetcher: graphQLFetcher,
+                fetcher,
             }),
             document.querySelector('#app'));
     </script>
@@ -53,16 +76,22 @@ pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
 <body>
     <div id="app"></div>
     <script src="//cdnjs.cloudflare.com/ajax/libs/fetch/2.0.3/fetch.js"></script>
+    <script src="//unpkg.com/subscriptions-transport-ws@0.8.3/browser/client.js"></script>
+    <script src="//unpkg.com/graphiql-subscriptions-fetcher@0.0.2/browser/client.js"></script>
     <script src="//cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
     <script src="//cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>
     <script src="//cdn.jsdelivr.net/npm/graphiql@0.17.5/graphiql.min.js"></script>
     <script>var GRAPHQL_URL = '{graphql_url}';</script>
+    <script>var usingSubscriptions = {using_subscriptions};</script>
+    <script>var GRAPHQL_SUBSCRIPTIONS_URL = '{graphql_subscriptions_url}';</script>
     {fetcher_source}
 </body>
 </html>
 "#,
         graphql_url = graphql_endpoint_url,
         stylesheet_source = stylesheet_source,
-        fetcher_source = fetcher_source
+        fetcher_source = fetcher_source,
+        graphql_subscriptions_url = subscriptions_endpoint,
+        using_subscriptions = subscriptions_endpoint_url.is_some(),
     )
 }
diff --git a/juniper_hyper/CHANGELOG.md b/juniper_hyper/CHANGELOG.md
index 9e139297..1acd9f3b 100644
--- a/juniper_hyper/CHANGELOG.md
+++ b/juniper_hyper/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 - Compatibility with the latest `juniper`.
 
+## Breaking Changes
+
+- `juniper_hyper::graphiql` now requires a second parameter for subscriptions
+
 # [[0.5.2] 2019-12-16](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.2)
 
 - Compatibility with the latest `juniper`.
diff --git a/juniper_hyper/examples/hyper_server.rs b/juniper_hyper/examples/hyper_server.rs
index ff6e586e..0d638d8e 100644
--- a/juniper_hyper/examples/hyper_server.rs
+++ b/juniper_hyper/examples/hyper_server.rs
@@ -31,7 +31,7 @@ async fn main() {
                 let ctx = ctx.clone();
                 async move {
                     match (req.method(), req.uri().path()) {
-                        (&Method::GET, "/") => juniper_hyper::graphiql("/graphql").await,
+                        (&Method::GET, "/") => juniper_hyper::graphiql("/graphql", None).await,
                         (&Method::GET, "/graphql") | (&Method::POST, "/graphql") => {
                             juniper_hyper::graphql(root_node, ctx, req).await
                         }
diff --git a/juniper_hyper/src/lib.rs b/juniper_hyper/src/lib.rs
index 8fe2bda4..710a609c 100644
--- a/juniper_hyper/src/lib.rs
+++ b/juniper_hyper/src/lib.rs
@@ -114,10 +114,16 @@ async fn parse_post_req<S: ScalarValue>(
         .map_err(GraphQLRequestError::BodyJSONError)
 }
 
-pub async fn graphiql(graphql_endpoint: &str) -> Result<Response<Body>, hyper::Error> {
+pub async fn graphiql(
+    graphql_endpoint: &str,
+    subscriptions_endpoint: Option<&str>,
+) -> Result<Response<Body>, hyper::Error> {
     let mut resp = new_html_response(StatusCode::OK);
     // XXX: is the call to graphiql_source blocking?
-    *resp.body_mut() = Body::from(juniper::http::graphiql::graphiql_source(graphql_endpoint));
+    *resp.body_mut() = Body::from(juniper::http::graphiql::graphiql_source(
+        graphql_endpoint,
+        subscriptions_endpoint,
+    ));
     Ok(resp)
 }
 
diff --git a/juniper_iron/CHANGELOG.md b/juniper_iron/CHANGELOG.md
index db3eb30d..83d83dad 100644
--- a/juniper_iron/CHANGELOG.md
+++ b/juniper_iron/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 - Compatibility with the latest `juniper`.
 
+## Breaking Changes
+
+- `juniper_iron::GraphiQLHandler::new` now requires a second parameter for subscriptions
+
 # [[0.6.2] 2019-12-16](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.2)
 
 - Compatibility with the latest `juniper`.
diff --git a/juniper_iron/examples/iron_server.rs b/juniper_iron/examples/iron_server.rs
index 20cc5dee..244403a9 100644
--- a/juniper_iron/examples/iron_server.rs
+++ b/juniper_iron/examples/iron_server.rs
@@ -29,7 +29,7 @@ fn main() {
         EmptyMutation::<Database>::new(),
         EmptySubscription::<Database>::new(),
     );
-    let graphiql_endpoint = GraphiQLHandler::new("/graphql");
+    let graphiql_endpoint = GraphiQLHandler::new("/graphql", None);
 
     mount.mount("/", graphiql_endpoint);
     mount.mount("/graphql", graphql_endpoint);
diff --git a/juniper_iron/src/lib.rs b/juniper_iron/src/lib.rs
index fc2ba9d1..de704574 100644
--- a/juniper_iron/src/lib.rs
+++ b/juniper_iron/src/lib.rs
@@ -159,6 +159,7 @@ pub struct GraphQLHandler<
 /// Handler that renders `GraphiQL` - a graphical query editor interface
 pub struct GraphiQLHandler {
     graphql_url: String,
+    subscription_url: Option<String>,
 }
 
 /// Handler that renders `GraphQL Playground` - a graphical query editor interface
@@ -275,9 +276,10 @@ impl GraphiQLHandler {
     ///
     /// The provided URL should point to the URL of the attached `GraphQLHandler`. It can be
     /// relative, so a common value could be `"/graphql"`.
-    pub fn new(graphql_url: &str) -> GraphiQLHandler {
+    pub fn new(graphql_url: &str, subscription_url: Option<&str>) -> GraphiQLHandler {
         GraphiQLHandler {
             graphql_url: graphql_url.to_owned(),
+            subscription_url: subscription_url.map(|s| s.to_owned()),
         }
     }
 }
@@ -326,7 +328,10 @@ impl Handler for GraphiQLHandler {
         Ok(Response::with((
             content_type,
             status::Ok,
-            juniper::http::graphiql::graphiql_source(&self.graphql_url),
+            juniper::http::graphiql::graphiql_source(
+                &self.graphql_url,
+                self.subscription_url.as_deref(),
+            ),
         )))
     }
 }
diff --git a/juniper_rocket/CHANGELOG.md b/juniper_rocket/CHANGELOG.md
index 31c0c22b..5359987b 100644
--- a/juniper_rocket/CHANGELOG.md
+++ b/juniper_rocket/CHANGELOG.md
@@ -3,6 +3,10 @@
 - Compatibility with the latest `juniper`.
 - Rocket integration does not require default features.
 
+## Breaking Changes
+
+- `juniper_rocket::graphiql_source` now requires a second parameter for subscriptions
+
 # [[0.5.2] 2019-12-16](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.2)
 
 - Compatibility with the latest `juniper`.
diff --git a/juniper_rocket/examples/rocket_server.rs b/juniper_rocket/examples/rocket_server.rs
index f352c36e..b0065a3d 100644
--- a/juniper_rocket/examples/rocket_server.rs
+++ b/juniper_rocket/examples/rocket_server.rs
@@ -11,7 +11,7 @@ type Schema = RootNode<'static, Query, EmptyMutation<Database>, EmptySubscriptio
 
 #[rocket::get("/")]
 fn graphiql() -> content::Html<String> {
-    juniper_rocket::graphiql_source("/graphql")
+    juniper_rocket::graphiql_source("/graphql", None)
 }
 
 #[rocket::get("/graphql?<request>")]
diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs
index c4a027c5..8816ac8d 100644
--- a/juniper_rocket/src/lib.rs
+++ b/juniper_rocket/src/lib.rs
@@ -71,9 +71,13 @@ where
 pub struct GraphQLResponse(pub Status, pub String);
 
 /// Generate an HTML page containing GraphiQL
-pub fn graphiql_source(graphql_endpoint_url: &str) -> content::Html<String> {
+pub fn graphiql_source(
+    graphql_endpoint_url: &str,
+    subscriptions_endpoint: Option<&str>,
+) -> content::Html<String> {
     content::Html(juniper::http::graphiql::graphiql_source(
         graphql_endpoint_url,
+        subscriptions_endpoint,
     ))
 }
 
diff --git a/juniper_rocket_async/src/lib.rs b/juniper_rocket_async/src/lib.rs
index 892311c5..efbb8c30 100644
--- a/juniper_rocket_async/src/lib.rs
+++ b/juniper_rocket_async/src/lib.rs
@@ -74,6 +74,7 @@ pub struct GraphQLResponse(pub Status, pub String);
 pub fn graphiql_source(graphql_endpoint_url: &str) -> content::Html<String> {
     content::Html(juniper::http::graphiql::graphiql_source(
         graphql_endpoint_url,
+        None,
     ))
 }
 
diff --git a/juniper_warp/CHANGELOG.md b/juniper_warp/CHANGELOG.md
index dbfb9967..9cbd277e 100644
--- a/juniper_warp/CHANGELOG.md
+++ b/juniper_warp/CHANGELOG.md
@@ -9,6 +9,7 @@ to `juniper` to be reused in other http integrations, since this implementation
 - Update `playground_filter` to support subscription endpoint URLs
 - Update `warp` to 0.2
 - Rename synchronous `execute` to `execute_sync`, add asynchronous `execute`
+- `juniper_warp::graphiql_filter` now requires a second parameter for subscriptions
 
 # [[0.5.2] 2019-12-16](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.2)
 
diff --git a/juniper_warp/examples/warp_server.rs b/juniper_warp/examples/warp_server.rs
index a6eb5217..7939c6ee 100644
--- a/juniper_warp/examples/warp_server.rs
+++ b/juniper_warp/examples/warp_server.rs
@@ -41,7 +41,7 @@ async fn main() {
     warp::serve(
         warp::get()
             .and(warp::path("graphiql"))
-            .and(juniper_warp::graphiql_filter("/graphql"))
+            .and(juniper_warp::graphiql_filter("/graphql", None))
             .or(homepage)
             .or(warp::path("graphql").and(graphql_filter))
             .with(log),
diff --git a/juniper_warp/src/lib.rs b/juniper_warp/src/lib.rs
index 19f4591a..471d68bc 100644
--- a/juniper_warp/src/lib.rs
+++ b/juniper_warp/src/lib.rs
@@ -299,20 +299,41 @@ type Response = Pin<
 /// # use warp::Filter;
 /// # use juniper_warp::graphiql_filter;
 /// #
-/// let graphiql_route = warp::path("graphiql").and(graphiql_filter("/graphql"));
+/// let graphiql_route = warp::path("graphiql").and(graphiql_filter("/graphql",
+/// None));
+/// ```
+///
+/// Or with subscriptions support, provide the subscriptions endpoint URL:
+///
+/// ```
+/// # extern crate warp;
+/// # extern crate juniper_warp;
+/// #
+/// # use warp::Filter;
+/// # use juniper_warp::graphiql_filter;
+/// #
+/// let graphiql_route = warp::path("graphiql").and(graphiql_filter("/graphql",
+/// Some("ws://localhost:8080/subscriptions")));
 /// ```
 pub fn graphiql_filter(
     graphql_endpoint_url: &'static str,
+    subscriptions_endpoint: Option<&'static str>,
 ) -> warp::filters::BoxedFilter<(warp::http::Response<Vec<u8>>,)> {
     warp::any()
-        .map(move || graphiql_response(graphql_endpoint_url))
+        .map(move || graphiql_response(graphql_endpoint_url, subscriptions_endpoint))
         .boxed()
 }
 
-fn graphiql_response(graphql_endpoint_url: &'static str) -> warp::http::Response<Vec<u8>> {
+fn graphiql_response(
+    graphql_endpoint_url: &'static str,
+    subscriptions_endpoint: Option<&'static str>,
+) -> warp::http::Response<Vec<u8>> {
     warp::http::Response::builder()
         .header("content-type", "text/html;charset=utf-8")
-        .body(juniper::http::graphiql::graphiql_source(graphql_endpoint_url).into_bytes())
+        .body(
+            juniper::http::graphiql::graphiql_source(graphql_endpoint_url, subscriptions_endpoint)
+                .into_bytes(),
+        )
         .expect("response is valid")
 }
 
@@ -568,14 +589,14 @@ mod tests {
 
     #[test]
     fn graphiql_response_does_not_panic() {
-        graphiql_response("/abcd");
+        graphiql_response("/abcd", None);
     }
 
     #[tokio::test]
     async fn graphiql_endpoint_matches() {
         let filter = warp::get()
             .and(warp::path("graphiql"))
-            .and(graphiql_filter("/graphql"));
+            .and(graphiql_filter("/graphql", None));
         let result = request()
             .method("GET")
             .path("/graphiql")
@@ -591,7 +612,7 @@ mod tests {
         let filter = warp::get()
             .and(warp::path("dogs-api"))
             .and(warp::path("graphiql"))
-            .and(graphiql_filter("/dogs-api/graphql"));
+            .and(graphiql_filter("/dogs-api/graphql", None));
         let response = request()
             .method("GET")
             .path("/dogs-api/graphiql")
@@ -609,6 +630,22 @@ mod tests {
         assert!(body.contains("<script>var GRAPHQL_URL = '/dogs-api/graphql';</script>"));
     }
 
+    #[tokio::test]
+    async fn graphiql_endpoint_with_subscription_matches() {
+        let filter = warp::get().and(warp::path("graphiql")).and(graphiql_filter(
+            "/graphql",
+            Some("ws:://localhost:8080/subscriptions"),
+        ));
+        let result = request()
+            .method("GET")
+            .path("/graphiql")
+            .header("accept", "text/html")
+            .filter(&filter)
+            .await;
+
+        assert!(result.is_ok());
+    }
+
     #[tokio::test]
     async fn playground_endpoint_matches() {
         let filter = warp::get()