diff --git a/website/src/docs/docs.json b/website/src/docs/docs.json
index 767f98f9fb2..8eb64644bfa 100644
--- a/website/src/docs/docs.json
+++ b/website/src/docs/docs.json
@@ -860,7 +860,97 @@
"versions": [
{
"path": "",
- "title": "v11",
+ "title": "v13",
+ "items": [
+ {
+ "path": "index",
+ "title": "Introduction"
+ },
+ {
+ "path": "get-started",
+ "title": "Get Started",
+ "items": [
+ {
+ "path": "index",
+ "title": "Blazor"
+ },
+ {
+ "path": "xamarin",
+ "title": "Xamarin"
+ },
+ {
+ "path": "console",
+ "title": "Console"
+ }
+ ]
+ },
+ {
+ "path": "subscriptions",
+ "title": "Subscriptions"
+ },
+ {
+ "path": "tooling",
+ "title": "Tooling / CLI"
+ },
+ {
+ "path": "caching",
+ "title": "Caching",
+ "items": [
+ {
+ "path": "index",
+ "title": "Overview"
+ },
+ {
+ "path": "entities",
+ "title": "Entities"
+ },
+ {
+ "path": "invalidation",
+ "title": "Invalidation"
+ }
+ ]
+ },
+ {
+ "path": "performance",
+ "title": "Performance",
+ "items": [
+ {
+ "path": "index",
+ "title": "Overview"
+ },
+ {
+ "path": "persisted-queries",
+ "title": "Persisted Queries"
+ },
+ {
+ "path": "persisted-state",
+ "title": "Persisted State"
+ }
+ ]
+ },
+ {
+ "path": "networking",
+ "title": "Networking",
+ "items": [
+ {
+ "path": "index",
+ "title": "Protocols"
+ },
+ {
+ "path": "authentication",
+ "title": "Authentication"
+ }
+ ]
+ },
+ {
+ "path": "scalars",
+ "title": "Scalars"
+ }
+ ]
+ },
+ {
+ "path": "v12",
+ "title": "v12",
"items": [
{
"path": "index",
diff --git a/website/src/docs/strawberryshake/get-started/index.md b/website/src/docs/strawberryshake/get-started/index.md
index 4016e43e3b6..3f603abe91b 100644
--- a/website/src/docs/strawberryshake/get-started/index.md
+++ b/website/src/docs/strawberryshake/get-started/index.md
@@ -14,6 +14,10 @@ In this tutorial, we will teach you:
- How to generate source code from .graphql files, that contain operations.
- How to use the generated client in a classical or reactive way.
+
+
# Step 1: Add the Strawberry Shake CLI tools
The Strawberry Shake tool will help you to setup your project to create a GraphQL client.
diff --git a/website/src/docs/strawberryshake/v12/caching/entities.md b/website/src/docs/strawberryshake/v12/caching/entities.md
new file mode 100644
index 00000000000..3d606d657ef
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/caching/entities.md
@@ -0,0 +1 @@
+> We are still working on the documentation for Strawberry Shake so help us by finding typos, missing things or write some additional docs with us.
diff --git a/website/src/docs/strawberryshake/v12/caching/index.md b/website/src/docs/strawberryshake/v12/caching/index.md
new file mode 100644
index 00000000000..eec3f9173b6
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/caching/index.md
@@ -0,0 +1,67 @@
+---
+title: "Caching"
+---
+
+> We are still working on the documentation for Strawberry Shake, so help us by finding typos, missing things, or write some additional docs with us.
+
+StrawberryShake stores the result of GraphQL requests in a normalized entity store. The entity store allows your client to execute GraphQL requests with various strategies to reduce the need for network requests. Moreover, the normalized entities are updated by every request the client does, which means that you can build fully reactive components that change as the state in the store changes.
+
+```mermaid
+sequenceDiagram
+ participant Generated Client
+ participant Operation Store
+ participant Entity Store
+ participant GraphQL Server
+ Generated Client->>Operation Store: Queries local store
+ Operation Store->>GraphQL Server: Queries GraphQL server
+ Note over Entity Store: Normalize response into entities
+ GraphQL Server->>Entity Store: Returns GraphQL response
+ Note over Operation Store: Builds operation result from entities
+ Entity Store->>Operation Store: Returns entities for operation
+ Operation Store->>Generated Client: Returns operation result
+```
+
+# Strategies
+
+We support three basic strategies to interact with the store and fetch data.
+
+## Network Only
+
+Network only is the simplest strategy and will fetch from the network and only then update the store. This means that our initial call will always get fresh data and at the same time update other request results watching the same entities.
+
+If we use the reactive APIs in combination with network only we will still get updates whenever other requests fetch data for the entities we are watching.
+
+## Cache First
+
+Cache first is essentially the opposite of network only since it will first fetch from the store, and if the store has the data needed, it will not make any network requests. If the store does not have the data needed, it will go to the network and try to get the data and update the store.
+
+## Cache and Network
+
+The last strategy is a combination of the first two. The client will first try to get the data from the store. This gives us fast data response time if the store already has the data. After that the store will update that data for this request with data from the network which in consequence will trigger our subscription and serve us new data.
+
+## Configuration
+
+The global strategy default can be set on our dependency injection setup method.
+
+```csharp
+builder.Services
+ .AddConferenceClient(ExecutionStrategy.CacheFirst) // <----
+ .ConfigureHttpClient(client => client.BaseAddress = new Uri("http://localhost:5050/graphql"))
+ .ConfigureWebSocketClient(client => client.Uri = new Uri("ws://localhost:5050/graphql"));
+```
+
+The global strategy default can then be overwritten by any `Watch` method for a particular request.
+
+```csharp
+storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(ExecutionStrategy.CacheFirst) // <----
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data!.Sessions!.Nodes)
+ .Subscribe(result =>
+ {
+ sessions = result;
+ StateHasChanged();
+ });
+```
diff --git a/website/src/docs/strawberryshake/v12/caching/invalidation.md b/website/src/docs/strawberryshake/v12/caching/invalidation.md
new file mode 100644
index 00000000000..3d606d657ef
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/caching/invalidation.md
@@ -0,0 +1 @@
+> We are still working on the documentation for Strawberry Shake so help us by finding typos, missing things or write some additional docs with us.
diff --git a/website/src/docs/strawberryshake/v12/configuration.md b/website/src/docs/strawberryshake/v12/configuration.md
new file mode 100644
index 00000000000..e4d67c3a48a
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/configuration.md
@@ -0,0 +1,30 @@
+# Configuring Strawberry Shake
+
+Strawberry Shake is configured by altering the `.graphqlrc.json` at the root of your project.
+All settings to into `extensions.strawberryShake` object.
+Here is a full configuration with all possibilities:
+
+```json
+{
+ // The path of the schema file, that will be used to generate the client.
+ // This setting may also be used by other tooling, because it is a default field of graphql-spec
+ "schema": "schema.graphql",
+ // The selector that determines, what files will be regarded as graphql documents
+ // This setting may also be used by other tooling, because it is a default field of graphql-spec
+ "documents": "**/*.graphql",
+ "extensions": {
+ // Here do only Strawberry Shake specific settings live
+ "strawberryShake": {
+ // The name of the generated client
+ "name": "ChatClient",
+ // The namespace of all the generated files of the client
+ "namespace": "Demo",
+ // The URL of the GraphQL api you want to consume with the client
+ "url": "https://workshop.chillicream.com/graphql/",
+ // Shall your client be based on dependency injection? If yes, all needed setup code
+ // will be generated for you, so that you only have to add the client to your DI container.
+ "dependencyInjection": true
+ }
+ }
+}
+```
diff --git a/website/src/docs/strawberryshake/v12/get-started/console.md b/website/src/docs/strawberryshake/v12/get-started/console.md
new file mode 100644
index 00000000000..9a88f1de3ad
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/get-started/console.md
@@ -0,0 +1,211 @@
+---
+title: "Get started with Strawberry Shake in a Console application"
+---
+
+> We are still working on the documentation for Strawberry Shake so help us by finding typos, missing things or write some additional docs with us.
+
+In this tutorial we will walk you through the basics of adding a Strawberry Shake GraphQL client to a console project. For this example we will create a simple console application and fetch some simple data from our demo backend.
+
+Strawberry Shake is not limited to console application and can be used with any .NET standard compliant library.
+
+In this tutorial, we will teach you:
+
+- How to add the Strawberry Shake CLI tools.
+- How to generate source code from .graphql files, that contain operations.
+- How to use the generated client in a classical or reactive way.
+- How to disable state management for ASP.NET core use-cases.
+
+## Step 1: Add the Strawberry Shake CLI tools
+
+The Strawberry Shake tool will help you to setup your project to create a GraphQL client.
+
+Open your preferred terminal and select a directory where you want to add the code of this tutorial.
+
+1. Create a dotnet tool-manifest.
+
+```bash
+dotnet new tool-manifest
+```
+
+2. Install the Strawberry Shake tools.
+
+```bash
+dotnet tool install StrawberryShake.Tools --local
+```
+
+## Step 2: Create a console project
+
+Next, we will create our console project so that we have a little playground.
+
+1. First, a new solution called `Demo.sln`.
+
+```bash
+dotnet new sln -n Demo
+```
+
+2. Create a new console application.
+
+```bash
+dotnet new console -n Demo
+```
+
+3. Add the project to the solution `Demo.sln`.
+
+```bash
+dotnet sln add ./Demo
+```
+
+## Step 3: Install the required packages
+
+Strawberry Shake supports multiple GraphQL transport protocols. In this example we will use the standard GraphQL over HTTP protocol to interact with our GraphQL server.
+
+1. Add the `StrawberryShake.Transport.Http` package to your project.
+
+```bash
+dotnet add Demo package StrawberryShake.Transport.Http
+```
+
+2. Add the `StrawberryShake.CodeGeneration.CSharp.Analyzers` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package StrawberryShake.CodeGeneration.CSharp.Analyzers
+```
+
+When using the HTTP protocol we also need the HttpClientFactory and the Microsoft dependency injection.
+
+3. Add the `Microsoft.Extensions.DependencyInjection` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package Microsoft.Extensions.DependencyInjection
+```
+
+3. Add the `Microsoft.Extensions.Http` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package Microsoft.Extensions.Http
+```
+
+## Step 4: Add a GraphQL client to your project using the CLI tools
+
+To add a client to your project, you need to run the `dotnet graphql init {{ServerUrl}} -n {{ClientName}}`.
+
+In this tutorial we will use our GraphQL workshop to create a list of sessions that we will add to our console application.
+
+> If you want to have a look at our GraphQL workshop head over [here](https://github.com/ChilliCream/graphql-workshop).
+
+1. Add the conference client to your console application.
+
+```bash
+dotnet graphql init https://workshop.chillicream.com/graphql/ -n ConferenceClient -p ./Demo
+```
+
+2. Customize the namespace of the generated client to be `Demo.GraphQL`. For this head over to the `.graphqlrc.json` and insert a namespace property to the `StrawberryShake` section.
+
+```json
+{
+ "schema": "schema.graphql",
+ "documents": "**/*.graphql",
+ "extensions": {
+ "strawberryShake": {
+ "name": "ConferenceClient",
+ "namespace": "Demo.GraphQL",
+ "url": "https://workshop.chillicream.com/graphql/",
+ "dependencyInjection": true
+ }
+ }
+}
+```
+
+Now that everything is in place let us write our first query to ask for a list of session titles of the conference API.
+
+3. Choose your favorite IDE and the solution. If your are using VSCode do the following:
+
+```bash
+code ./Demo
+```
+
+4. Create new query document `GetSessions.graphql` with the following content:
+
+```graphql
+query GetSessions {
+ sessions(order: { title: ASC }) {
+ nodes {
+ title
+ }
+ }
+}
+```
+
+5. Compile your project.
+
+```bash
+dotnet build
+```
+
+With the project compiled you now should see a directory `Generated`. The generated code is just there for the IDE, the actual code was injected directly into roslyn through source generators.
+
+![Visual Studio code showing the generated directory.](../../shared/berry_console_generated.png)
+
+1. Head over to the `Program.cs` and add the new `ConferenceClient` to the dependency injection.
+
+> In some IDEs it is still necessary to reload the project after the code was generated to update the IntelliSense. So, if you have any issues in the next step with IntelliSense just reload the project and everything should be fine.
+
+```csharp
+using System;
+using Microsoft.Extensions.DependencyInjection;
+using Demo.GraphQL;
+
+namespace Demo
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ var serviceCollection = new ServiceCollection();
+
+ serviceCollection
+ .AddConferenceClient()
+ .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://workshop.chillicream.com/graphql"));
+
+ IServiceProvider services = serviceCollection.BuildServiceProvider();
+
+ IConferenceClient client = services.GetRequiredService();
+ }
+ }
+}
+```
+
+## Step 5: Use the ConferenceClient to perform a simple fetch
+
+In this section we will perform a simple fetch with our `ConferenceClient` and output the result to the console.
+
+1. Head over to `Program.cs`.
+
+2. Add the following code to your main method to execute the `GetSessions` query.
+
+```csharp
+static async Task Main(string[] args)
+{
+ var serviceCollection = new ServiceCollection();
+
+ serviceCollection
+ .AddConferenceClient()
+ .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://workshop.chillicream.com/graphql"));
+
+ IServiceProvider services = serviceCollection.BuildServiceProvider();
+
+ IConferenceClient client = services.GetRequiredService();
+
+ var result = await client.GetSessions.ExecuteAsync();
+ result.EnsureNoErrors();
+
+ foreach (var session in result.Data.Sessions.Nodes)
+ {
+ Console.WriteLine(session.Title);
+ }
+}
+```
+
+3. Start the console application with `dotnet run --project ./Demo` and see if your code works.
+
+![Started console application that shows a list of sessions](../../shared/berry_console_session_list.png)
diff --git a/website/src/docs/strawberryshake/v12/get-started/index.md b/website/src/docs/strawberryshake/v12/get-started/index.md
new file mode 100644
index 00000000000..4016e43e3b6
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/get-started/index.md
@@ -0,0 +1,707 @@
+---
+title: "Get started with Strawberry Shake and Blazor"
+---
+
+> We are still working on the documentation for Strawberry Shake so help us by finding typos, missing things or write some additional docs with us.
+
+In this tutorial we will walk you through the basics of adding a Strawberry Shake GraphQL client to a Blazor for WebAssembly project. For this example we will create a Blazor for WebAssembly application and fetch some simple data from our demo backend.
+
+Strawberry Shake is not limited to Blazor and can be used with any .NET standard compliant library.
+
+In this tutorial, we will teach you:
+
+- How to add the Strawberry Shake CLI tools.
+- How to generate source code from .graphql files, that contain operations.
+- How to use the generated client in a classical or reactive way.
+
+# Step 1: Add the Strawberry Shake CLI tools
+
+The Strawberry Shake tool will help you to setup your project to create a GraphQL client.
+
+Open your preferred terminal and select a directory where you want to add the code of this tutorial.
+
+1. Create a dotnet tool-manifest.
+
+```bash
+dotnet new tool-manifest
+```
+
+2. Install the Strawberry Shake tools.
+
+```bash
+dotnet tool install StrawberryShake.Tools --local
+```
+
+# Step 2: Create a Blazor WebAssembly project
+
+Next, we will create our Blazor project so that we have a little playground.
+
+1. First, a new solution called `Demo.sln`.
+
+```bash
+dotnet new sln -n Demo
+```
+
+2. Create a new Blazor for WebAssembly application.
+
+```bash
+dotnet new blazorwasm -n Demo
+```
+
+3. Add the project to the solution `Demo.sln`.
+
+```bash
+dotnet sln add ./Demo
+```
+
+# Step 3: Install the required packages
+
+Strawberry Shake supports multiple GraphQL transport protocols. In this example we will use the standard GraphQL over HTTP protocol to interact with our GraphQL server.
+
+1. Add the `StrawberryShake.Transport.Http` package to your project.
+
+```bash
+dotnet add Demo package StrawberryShake.Transport.Http
+```
+
+2. Add the `StrawberryShake.CodeGeneration.CSharp.Analyzers` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package StrawberryShake.CodeGeneration.CSharp.Analyzers
+```
+
+When using the HTTP protocol we also need the HttpClientFactory and the Microsoft dependency injection.
+
+3. Add the `Microsoft.Extensions.DependencyInjection` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package Microsoft.Extensions.DependencyInjection
+```
+
+3. Add the `Microsoft.Extensions.Http` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package Microsoft.Extensions.Http
+```
+
+# Step 4: Add a GraphQL client to your project using the CLI tools
+
+To add a client to your project, you need to run the `dotnet graphql init {{ServerUrl}} -n {{ClientName}}`.
+
+In this tutorial we will use our GraphQL workshop to create a list of sessions that we will add to our Blazor application.
+
+> If you want to have a look at our GraphQL workshop head over [here](https://github.com/ChilliCream/graphql-workshop).
+
+1. Add the conference client to your Blazor application.
+
+```bash
+dotnet graphql init https://workshop.chillicream.com/graphql/ -n ConferenceClient -p ./Demo
+```
+
+2. Customize the namespace of the generated client to be `Demo.GraphQL`. For this head over to the `.graphqlrc.json` and insert a namespace property to the `StrawberryShake` section.
+
+```json
+{
+ "schema": "schema.graphql",
+ "documents": "**/*.graphql",
+ "extensions": {
+ "strawberryShake": {
+ "name": "ConferenceClient",
+ "namespace": "Demo.GraphQL",
+ "url": "https://workshop.chillicream.com/graphql/",
+ "dependencyInjection": true
+ }
+ }
+}
+```
+
+Now that everything is in place let us write our first query to ask for a list of session titles of the conference API.
+
+3. Choose your favorite IDE and the solution. If your are using VSCode do the following:
+
+```bash
+code ./Demo
+```
+
+4. Create new query document `GetSessions.graphql` with the following content:
+
+```graphql
+query GetSessions {
+ sessions(order: { title: ASC }) {
+ nodes {
+ title
+ }
+ }
+}
+```
+
+5. Compile your project.
+
+```bash
+dotnet build
+```
+
+With the project compiled you now should see a directory `Generated`. The generated code is just there for the IDE, the actual code was injected directly into roslyn through source generators.
+
+![Visual Studio code showing the generated directory.](../../shared/berry_generated.png)
+
+6. Head over to the `Program.cs` and add the new `ConferenceClient` to the dependency injection.
+
+> In some IDEs it is still necessary to reload the project after the code was generated to update the IntelliSense. So, if you have any issues in the next step with IntelliSense just reload the project and everything should be fine.
+
+```csharp
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ var builder = WebAssemblyHostBuilder.CreateDefault(args);
+ builder.RootComponents.Add("#app");
+
+ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
+
+ builder.Services
+ .AddConferenceClient()
+ .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://workshop.chillicream.com/graphql"));
+
+ await builder.Build().RunAsync();
+ }
+}
+```
+
+7. Go to `_Imports.razor` and add `Demo.GraphQL` to the common imports
+
+```csharp
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.AspNetCore.Components.WebAssembly.Http
+@using Microsoft.JSInterop
+@using Demo
+@using Demo.Shared
+@using Demo.GraphQL
+@using StrawberryShake
+```
+
+# Step 5: Use the ConferenceClient to perform a simple fetch
+
+In this section we will perform a simple fetch with our `ConferenceClient`. We will not yet look at state or other things that come with our client but just perform a simple fetch.
+
+1. Head over to `Pages/Index.razor`.
+
+2. Add inject the `ConferenceClient` beneath the `@pages` directive.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+```
+
+3. Introduce a code directive at the bottom of the file.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+@code {
+
+}
+```
+
+4. Now lets fetch the titles with our client.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+@code {
+ private string[] titles = Array.Empty();
+
+ protected override async Task OnInitializedAsync()
+ {
+ var result = await ConferenceClient.GetSessions.ExecuteAsync();
+ titles = result.Data.Sessions.Nodes.Select(t => t.Title).ToArray();
+ }
+}
+```
+
+5. Last, lets render the titles on our page as a list.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+
+ @foreach (string title in titles) {
+
@title
+ }
+
+
+@code {
+ private string[] titles = Array.Empty();
+
+ protected override async Task OnInitializedAsync()
+ {
+ var result = await ConferenceClient.GetSessions.ExecuteAsync();
+ titles = result.Data.Sessions.Nodes.Select(t => t.Title).ToArray();
+ }
+}
+```
+
+5. Start the Blazor application with `dotnet run --project ./Demo` and see if your code works.
+
+![Started Blazor application in Microsoft Edge](../../shared/berry_session_list.png)
+
+# Step 6: Using the built-in store with reactive APIs.
+
+The simple fetch of our data works. But every time we visit the index page it will fetch the data again although the data does not change often. Strawberry Shake also comes with state management where you can control the entity store and update it when you need to. In order to best interact with the store we will use `System.Reactive` from Microsoft. Lets get started :)
+
+1. Install the package `System.Reactive`.
+
+```bash
+dotnet add Demo package System.Reactive
+```
+
+2. Next, let us update the `_Imports.razor` with some more imports, namely `System`, `System.Reactive.Linq`, `System.Linq` and `StrawberryShake`.
+
+```csharp
+@using System
+@using System.Reactive.Linq
+@using System.Linq
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.AspNetCore.Components.WebAssembly.Http
+@using Microsoft.JSInterop
+@using Demo
+@using Demo.Shared
+@using Demo.GraphQL
+@using StrawberryShake
+```
+
+3. Head back to `Pages/Index.razor` and replace the code section with the following code:
+
+```csharp
+private string[] titles = Array.Empty();
+private IDisposable storeSession;
+
+protected override void OnInitialized()
+{
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(StrawberryShake.ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data.Sessions.Nodes.Select(t => t.Title).ToArray())
+ .Subscribe(result =>
+ {
+ titles = result;
+ StateHasChanged();
+ });
+}
+```
+
+Instead of fetching the data we watch the data for our request. Every time entities of our results are updated in the entity store our subscribe method will be triggered.
+
+Also we specified on our watch method that we want to first look at the store and only if there is nothing in the store we want to fetch the data from the network.
+
+Last, note that we are storing a disposable on our component state called `storeSession`. This represents our session with the store. We need to dispose the session when we no longer display our component.
+
+4. Implement `IDisposable` and handle the `storeSession` dispose.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+@implements IDisposable
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+
+@foreach (var title in titles)
+{
+
@title
+}
+
+
+@code {
+ private string[] titles = Array.Empty();
+ private IDisposable storeSession;
+
+ protected override void OnInitialized()
+ {
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(StrawberryShake.ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data.Sessions.Nodes.Select(t => t.Title).ToArray())
+ .Subscribe(result =>
+ {
+ titles = result;
+ StateHasChanged();
+ });
+ }
+
+ public void Dispose()
+ {
+ storeSession?.Dispose();
+ }
+}
+```
+
+Every time we move away from our index page Blazor will dispose our page which consequently will dispose our store session.
+
+5. Start the Blazor application with `dotnet run --project ./Demo` and see if your code works.
+
+![Started Blazor application in Microsoft Edge](../../shared/berry_session_list.png)
+
+The page will look unchanged.
+
+6. Next, open the developer tools of your browser and switch to the developer tools console. Refresh the site so that we get a fresh output.
+
+![Microsoft Edge developer tools show just one network interaction.](../../shared/berry_session_list_network.png)
+
+7. Switch between the `Index` and the `Counter` page (back and forth) and watch the console output.
+
+The Blazor application just fetched a single time from the network and now only gets the data from the store.
+
+# Step 7: Using GraphQL mutations
+
+In this step we will introduce a mutation that will allow us to rename a session. For this we need to change our Blazor page a bit.
+
+1. We need to get the session id for our session so that we can call the `renameSession` mutation. For this we will rewrite our `GetSessions` operation.
+
+```graphql
+query GetSessions {
+ sessions(order: { title: ASC }) {
+ nodes {
+ ...SessionInfo
+ }
+ }
+}
+
+fragment SessionInfo on Session {
+ id
+ title
+}
+```
+
+2. Next we need to restructure the `Index.razor` page. We will get rid of the Blazor default content and rework our list to use our fragment `SessionInfo`. Further, we will introduce a button to our list so that we have a hook to start editing items from our list.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+@implements IDisposable
+
+
Sessions
+
+
+@foreach (ISessionInfo session in sessions)
+{
+
@session.Title
+}
+
+
+@code {
+ private IReadOnlyList sessions = Array.Empty();
+ private IDisposable storeSession;
+
+ protected override void OnInitialized()
+ {
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data!.Sessions!.Nodes)
+ .Subscribe(result =>
+ {
+ sessions = result;
+ StateHasChanged();
+ });
+ }
+
+ private void OnClickSession(ISessionInfo session)
+ {
+
+ }
+
+ public void Dispose()
+ {
+ storeSession?.Dispose();
+ }
+}
+```
+
+3. Next, we will define the GraphQL mutation by adding a new GraphQL document `RenameSession.graphql`.
+
+```graphql
+mutation RenameSession($sessionId: ID!, $title: String!) {
+ renameSession(input: { sessionId: $sessionId, title: $title }) {
+ session {
+ ...SessionInfo
+ }
+ }
+}
+```
+
+4. Rebuild, the project so that the source generator will create all our new types.
+
+5. Go back to the `Index.razor` page and lets add some state for our edit controls.
+
+```csharp
+private ISessionInfo selectedSession;
+private string title;
+```
+
+The page should now look like the following:
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+@implements IDisposable
+
+
Sessions
+
+
+@foreach (ISessionInfo session in sessions)
+{
+
@session.Title
+}
+
+
+@code {
+ private IReadOnlyList sessions = Array.Empty();
+ private IDisposable storeSession;
+ private ISessionInfo selectedSession;
+ private string title;
+
+ protected override void OnInitialized()
+ {
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data!.Sessions!.Nodes)
+ .Subscribe(result =>
+ {
+ sessions = result;
+ StateHasChanged();
+ });
+ }
+
+ private void OnClickSession(ISessionInfo session)
+ {
+
+ }
+
+ public void Dispose()
+ {
+ storeSession?.Dispose();
+ }
+}
+```
+
+6. Now, lets put some controls in to let the user edit the title of one of our sessions.
+
+```csharp
+@if (selectedSession is not null)
+{
+
+
Edit Session Title:
+
+
+}
+```
+
+The page should now look like the following:
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+@implements IDisposable
+
+
Sessions
+
+
+@foreach (ISessionInfo session in sessions)
+{
+
@session.Title
+}
+
+
+@if (selectedSession is not null)
+{
+
+
Edit Session Title:
+
+
+}
+
+@code {
+ private IReadOnlyList sessions = Array.Empty();
+ private IDisposable storeSession;
+ private ISessionInfo selectedSession;
+ private string title;
+
+ protected override void OnInitialized()
+ {
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data!.Sessions!.Nodes)
+ .Subscribe(result =>
+ {
+ sessions = result;
+ StateHasChanged();
+ });
+ }
+
+ private void OnClickSession(ISessionInfo session)
+ {
+
+ }
+
+ public void Dispose()
+ {
+ storeSession?.Dispose();
+ }
+}
+```
+
+7. Next, we want to wire the controls up with the click. For that replace the `OnClickSession` method with the following code:
+
+```csharp
+private void OnClickSession(ISessionInfo session)
+{
+ selectedSession = session;
+ title = session.Title;
+ StateHasChanged();
+}
+```
+
+8. Add, a new method that now executes our new mutation `RenameSession`.
+
+```csharp
+private async Task OnSaveTitle()
+{
+ await ConferenceClient.RenameSession.ExecuteAsync(selectedSession.Id, title);
+ selectedSession = null;
+ title = null;
+ StateHasChanged();
+}
+```
+
+The page should now look like the following:
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+@implements IDisposable
+
+
Sessions
+
+
+@foreach (ISessionInfo session in sessions)
+{
+
@session.Title
+}
+
+
+@if (selectedSession is not null)
+{
+
+
Edit Session Title:
+
+
+}
+
+@code {
+ private IReadOnlyList sessions = Array.Empty();
+ private IDisposable storeSession;
+ private ISessionInfo selectedSession;
+ private string title;
+
+ protected override void OnInitialized()
+ {
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data!.Sessions!.Nodes)
+ .Subscribe(result =>
+ {
+ sessions = result;
+ StateHasChanged();
+ });
+ }
+
+ private void OnClickSession(ISessionInfo session)
+ {
+ selectedSession = session;
+ title = session.Title;
+ StateHasChanged();
+ }
+
+ private async Task OnSaveTitle()
+ {
+ await ConferenceClient.RenameSession.ExecuteAsync(selectedSession.Id, title);
+ selectedSession = null;
+ title = null;
+ StateHasChanged();
+ }
+
+ public void Dispose()
+ {
+ storeSession?.Dispose();
+ }
+}
+```
+
+9. Start the Blazor application with `dotnet run --project ./Demo` and see if your code works.
+
+![Started Blazor application in Microsoft Edge](../../shared/berry_mutation_1.png)
+
+10. Click on the edit button of one of the sessions.
+
+![Clicked on session edit button](../../shared/berry_mutation_2.png)
+
+11. Change the title of the session and click save.
+
+![Clicked on session edit button](../../shared/berry_mutation_3.png)
+
+11. The item is now changed in the list although we have not explicitly written any code to update the item in our list component.
+
+![Clicked on session edit button](../../shared/berry_mutation_4.png)
+
+Strawberry Shake knows about your entities and how they are connected. Whenever one request updates the state, all components referring to data of the linked entities are updated.
diff --git a/website/src/docs/strawberryshake/v12/get-started/xamarin.md b/website/src/docs/strawberryshake/v12/get-started/xamarin.md
new file mode 100644
index 00000000000..db1a2fd4515
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/get-started/xamarin.md
@@ -0,0 +1,406 @@
+---
+title: "Get started with Strawberry Shake and Xamarin"
+---
+
+> We are still working on the documentation for Strawberry Shake so help us by finding typos, missing things or write some additional docs with us.
+
+In this tutorial we will walk you through the basics of adding a Strawberry Shake GraphQL client to a .NET project. For this example we will create a Blazor for WebAssembly application and fetch some simple data from our demo backend.
+
+Strawberry Shake is not limited to Blazor and can be used with any .NET standard compliant library.
+
+In this tutorial, we will teach you:
+
+- How to add the Strawberry Shake CLI tools.
+- How to generate source code from .graphql files, that contain operations.
+- How to use the generated client in a classical or reactive way.
+
+## Step 1: Add the Strawberry Shake CLI tools
+
+The Strawberry Shake tool will help you to setup your project to create a GraphQL client.
+
+Open your preferred terminal and select a directory where you want to add the code of this tutorial.
+
+1. Create a dotnet tool-manifest.
+
+```bash
+dotnet new tool-manifest
+```
+
+2. Install the Strawberry Shake tools.
+
+```bash
+dotnet tool install StrawberryShake.Tools --local
+```
+
+## Step 2: Create a Blazor WebAssembly project
+
+Next, we will create our Blazor project so that we have a little playground.
+
+1. First, a new solution called `Demo.sln`.
+
+```bash
+dotnet new sln -n Demo
+```
+
+2. Create a new Blazor for WebAssembly application.
+
+```bash
+dotnet new wasm -n Demo
+```
+
+3. Add the project to the solution `Demo.sln`.
+
+```bash
+dotnet sln add ./Demo
+```
+
+## Step 3: Install the required packages
+
+Strawberry Shake supports multiple GraphQL transport protocols. In this example we will use the standard GraphQL over HTTP protocol to interact with our GraphQL server.
+
+1. Add the `StrawberryShake.Transport.Http` package to your project.
+
+```bash
+dotnet add Demo package StrawberryShake.Transport.Http
+```
+
+2. Add the `StrawberryShake.CodeGeneration.CSharp.Analyzers` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package StrawberryShake.CodeGeneration.CSharp.Analyzers
+```
+
+When using the HTTP protocol we also need the HttpClientFactory and the Microsoft dependency injection.
+
+3. Add the `Microsoft.Extensions.DependencyInjection` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package Microsoft.Extensions.DependencyInjection
+```
+
+3. Add the `Microsoft.Extensions.Http` package to your project in order to add our code generation.
+
+```bash
+dotnet add Demo package Microsoft.Extensions.Http
+```
+
+## Step 4: Add a GraphQL client to your project using the CLI tools
+
+To add a client to your project, you need to run the `dotnet graphql init {{ServerUrl}} -n {{ClientName}}`.
+
+In this tutorial we will use our GraphQL workshop to create a list of sessions that we will add to our Blazor application.
+
+> If you want to have a look at our GraphQL workshop head over [here](https://github.com/ChilliCream/graphql-workshop).
+
+1. Add the conference client to your Blazor application.
+
+```bash
+dotnet graphql init https://workshop.chillicream.com/graphql/ -n ConferenceClient -p ./Demo
+```
+
+2. Customize the namespace of the generated client to be `Demo.GraphQL`. For this head over to the `.graphqlrc.json` and insert a namespace property to the `StrawberryShake` section.
+
+```json
+{
+ "schema": "schema.graphql",
+ "documents": "**/*.graphql",
+ "extensions": {
+ "strawberryShake": {
+ "name": "ConferenceClient",
+ "namespace": "Demo.GraphQL",
+ "url": "https://workshop.chillicream.com/graphql/",
+ "dependencyInjection": true
+ }
+ }
+}
+```
+
+Now that everything is in place let us write our first query to ask for a list of session titles of the conference API.
+
+3. Choose your favorite IDE and the solution. If your are using VSCode do the following:
+
+```bash
+code ./Demo
+```
+
+4. Create new query document `GetSessions.graphql` with the following content:
+
+```graphql
+query GetSessions {
+ sessions(order: { title: ASC }) {
+ nodes {
+ title
+ }
+ }
+}
+```
+
+5. Compile your project.
+
+```bash
+dotnet build
+```
+
+With the project compiled you now should see a directory `Generated`. The generated code is just there for the IDE, the actual code was injected directly into roslyn through source generators.
+
+![Visual Studio code showing the generated directory.](../shared/berry_generated.png)
+
+6. Head over to the `Program.cs` and add the new `ConferenceClient` to the dependency injection.
+
+> In some IDEs it is still necessary to reload the project after the code was generated to update the IntelliSense. So, if you have any issues in the next step with IntelliSense just reload the project and everything should be fine.
+
+```csharp
+public class Program
+{
+ public static async Task Main(string[] args)
+ {
+ var builder = WebAssemblyHostBuilder.CreateDefault(args);
+ builder.RootComponents.Add("#app");
+
+ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
+
+ builder.Services
+ .AddConferenceClient()
+ .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://workshop.chillicream.com/graphql"));
+
+ await builder.Build().RunAsync();
+ }
+}
+```
+
+7. Go to `_Imports.razor` and add `Demo.GraphQL` to the common imports
+
+```razor
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.AspNetCore.Components.WebAssembly.Http
+@using Microsoft.JSInterop
+@using Demo
+@using Demo.Shared
+@using Demo.GraphQL
+```
+
+## Step 5: Use the ConferenceClient to perform a simple fetch
+
+In this section we will perform a simple fetch with our `ConferenceClient`. We will not yet look at state or other things that come with our client but just perform a simple fetch.
+
+1. Head over to `Pages/Index.razor`.
+
+2. Add inject the `ConferenceClient` beneath the `@pages` directive.
+
+```html
+@page "/" @inject ConferenceClient ConferenceClient;
+```
+
+3. Introduce a code directive at the bottom of the file.
+
+```html
+@page "/" @inject ConferenceClient ConferenceClient;
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+@code { }
+```
+
+4. Now lets fetch the titles with our client.
+
+```html
+@page "/" @inject ConferenceClient ConferenceClient;
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+@code { private string[] titles = Array.Empty(); protected override async Task OnInitializedAsync() { // Execute our
+ GetSessions query var result = await
+ ConferenceClient.GetSessions.ExecuteAsync(); // aggregate the titles from the
+ result titles = result.Data.Sessions.Nodes.Select(t => t.Title).ToArray(); //
+ signal the components that the state has changed. StateHasChanged(); }
+ }
+```
+
+5. Last, lets render the titles on our page as a list.
+
+```html
+@page "/" @inject ConferenceClient ConferenceClient;
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+
+ @foreach (string title in titles) {
+
@title
+ }
+
+
+@code { private string[] titles = Array.Empty(); protected override async Task OnInitializedAsync() { // Execute our
+ GetSessions query var result = await
+ ConferenceClient.GetSessions.ExecuteAsync(); // aggregate the titles from the
+ result titles = result.Data.Sessions.Nodes.Select(t => t.Title).ToArray(); //
+ signal the components that the state has changed. StateHasChanged(); }
+ }
+```
+
+5. Start the Blazor application with `dotnet run --project ./Demo` and see if your code works.
+
+![Started Blazor application in Microsoft Edge](../shared/berry_session_list.png)
+
+## Step 6: Using the built-in store with reactive APIs.
+
+The simple fetch of our data works. But every time we visit the index page it will fetch the data again although the data does not change often. Strawberry Shake also comes with state management where you can control the entity store and update it when you need to. In order to best interact with the store we will use `System.Reactive` from Microsoft. Lets get started :)
+
+1. Install the package `System.Reactive`.
+
+```bash
+dotnet add Demo package System.Reactive
+```
+
+2. Next, let us update the `_Imports.razor` with some more imports, namely `System`, `System.Reactive.Linq`, `System.Linq` and `StrawberryShake`.
+
+```csharp
+@using System
+@using System.Reactive.Linq
+@using System.Linq
+@using System.Net.Http
+@using System.Net.Http.Json
+@using Microsoft.AspNetCore.Components.Forms
+@using Microsoft.AspNetCore.Components.Routing
+@using Microsoft.AspNetCore.Components.Web
+@using Microsoft.AspNetCore.Components.Web.Virtualization
+@using Microsoft.AspNetCore.Components.WebAssembly.Http
+@using Microsoft.JSInterop
+@using Demo
+@using Demo.Shared
+@using Demo.GraphQL
+@using StrawberryShake
+```
+
+3. Head back to `Pages/Index.razor` and replace the code section with the following code:
+
+```csharp
+private string[] titles = Array.Empty();
+private IDisposable storeSession;
+
+protected override void OnInitialized()
+{
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(StrawberryShake.ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data.Sessions.Nodes.Select(t => t.Title).ToArray())
+ .Subscribe(result =>
+ {
+ titles = result;
+ StateHasChanged();
+ });
+}
+```
+
+Instead of fetching the data we watch the data for our request. Every time entities of our results are updated in the entity store our subscribe method will be triggered.
+
+Also we specified on our watch method that we want to first look at the store and only of there is nothing in the store we want to fetch the data from the network.
+
+Last, note that we are storing a disposable on our component state called `storeSession`. This represents our session with the store. We need to dispose the session when we no longer display our component.
+
+4. Implement `IDisposable` and handle the `storeSession` dispose.
+
+```csharp
+@page "/"
+@inject ConferenceClient ConferenceClient;
+@implements IDisposable
+
+
Hello, world!
+
+Welcome to your new app.
+
+
+
+
+@foreach (var title in titles)
+{
+
@title
+}
+
+
+@code {
+ private string[] titles = Array.Empty();
+ private IDisposable storeSession;
+
+ protected override void OnInitialized()
+ {
+ storeSession =
+ ConferenceClient
+ .GetSessions
+ .Watch(StrawberryShake.ExecutionStrategy.CacheFirst)
+ .Where(t => !t.Errors.Any())
+ .Select(t => t.Data.Sessions.Nodes.Select(t => t.Title).ToArray())
+ .Subscribe(result =>
+ {
+ titles = result;
+ StateHasChanged();
+ });
+ }
+
+ public void Dispose()
+ {
+ storeSession?.Dispose();
+ }
+}
+```
+
+Every time we move away from our index page Blazor will dispose our page which consequently will dispose our store session.
+
+5. Start the Blazor application with `dotnet run --project ./Demo` and see if your code works.
+
+![Started Blazor application in Microsoft Edge](../shared/berry_session_list.png)
+
+The page will look unchanged.
+
+6. Next, open the developer tools of your browser and switch to the developer tools console. Refresh the site so that we get a fresh output.
+
+![Microsoft Edge developer tools show just one network interaction.](../shared/berry_session_list_network.png)
+
+7. Switch between the `Index` and the `Counter` page (back and forth) and watch the console output.
+
+The Blazor application just fetched a single time from the network and now only gets the data from the store.
+
+## Step 7: Using GraphQL mutations
+
+In this step we will introduce a mutation that will allow us to rename a session. For this we need to change our Blazor page a bit.
+
+1. We need to get the session id for our session so that we can call the `renameSession` mutation. For this we will rewrite our `GetSessions` operation.
+
+```graphql
+query GetSessions {
+ sessions(order: { title: ASC }) {
+ nodes {
+ ...SessionInfo
+ }
+ }
+}
+
+fragment SessionInfo on Session {
+ id
+ title
+}
+```
+
+2. Next we need to restructure the `Index.razor` page.
diff --git a/website/src/docs/strawberryshake/v12/index.md b/website/src/docs/strawberryshake/v12/index.md
new file mode 100644
index 00000000000..ab76804941a
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/index.md
@@ -0,0 +1,15 @@
+# Introduction
+
+> We are still working on the documentation for Strawberry Shake so help us by finding typos, missing things or write some additional docs with us.
+
+Strawberry Shake is an open-source GraphQL client that is compliant with the newest GraphQL draft spec, which makes Strawberry Shake compatible with all GraphQL compliant servers like Hot Chocolate, Apollo Server, GraphQL Java and various other servers out there.
+
+Strawberry Shake removes the complexity of state management and lets you interact with local and remote data through GraphQL.
+
+You can use Strawberry Shake to:
+
+- Generate a C# client from your GraphQL queries.
+- Interact with local and remote data through GraphQL.
+- Use reactive APIs to interact with your state.
+
+Let's [get started](/docs/strawberryshake/get-started) with Strawberry Shake!
diff --git a/website/src/docs/strawberryshake/v12/networking/authentication.md b/website/src/docs/strawberryshake/v12/networking/authentication.md
new file mode 100644
index 00000000000..776b36162a4
--- /dev/null
+++ b/website/src/docs/strawberryshake/v12/networking/authentication.md
@@ -0,0 +1,156 @@
+---
+title: "Authentication"
+---
+
+To access a protected API with Strawberry Shake, you need to proof the user's identity to the server.
+Each network protocol of Strawberry Shake handles authentication a bit different.
+
+# HTTP
+
+Strawberry Shake uses the `HttpClientFactory` to generate a `HttpClient` on every request.
+You can either register a `HttpClient` directly on the `ServiceCollection` or use the `ConfigureHttpClient` method on the client builder.
+
+## ConfigureHttpClient
+
+The generated extension method to register the client on the serivce collection, returns a builder that can be used to configure the http client.
+
+```csharp
+ services
+ .AddConferenceClient()
+ .ConfigureHttpClient(client =>
+ {
+ client.BaseAddress =
+ new Uri("https://workshop.chillicream.com/graphql/");
+ client.DefaultRequestHeaders.Authorization =
+ new AuthenticationHeaderValue("Bearer", "Your Oauth token");
+ });
+```
+
+There is an overload of the `ConfigureHttpClient` method that provides access to the `IServiceProvider`, in case the access token is stored there.
+
+```csharp
+services
+ .AddConferenceClient()
+ .ConfigureHttpClient((serviceProvider, client) =>
+ {
+ var token = serviceProvider.GetRequiredService().Token;
+ });
+```
+
+The second parameter of `ConfigureHttpClient` allows direct access to the `HttpClientBuilder`. Use this delegate to register extensions like Polly.
+
+```csharp
+services
+ .AddConferenceClient()
+ .ConfigureHttpClient(
+ client => { /*...*/ },
+ builder => builder.AddPolly());
+
+```
+
+## HttpClientFactory
+
+In case you want to configure the `HttpClient` directly on the `ServiceCollection`, Strawberry Shake generates you a property `ClientName`, that you can use to set the correct name for the client.
+
+```csharp
+services.AddHttpClient(
+ ConferenceClient.ClientName,
+ client => client.BaseAddress =
+ new Uri("https://workshop.chillicream.com/graphql/"));
+
+services.AddConferenceClient();
+```
+
+# Websockets
+
+There are three common ways to do authentication a request over a web socket. You can either specify the authentication headers, use cookies or send the access token with the first message over the socket.
+Similar to the `HttpClient`, you can configure the a web socket client over the client builder or the `ServiceCollection`.
+
+Strawberry Shake uses a `IWebSocketClient` that provides a similar interface as the `HttpClient` has.
+
+## ConfigureWebsocketClient
+
+You can configure the web socket client directly on the client builder after you registered it on the service collection.
+
+```csharp
+services
+ .AddConferenceClient()
+ .ConfigureWebSocketClient(client =>
+ {
+ client.Uri = new Uri("ws://localhost:" + port + "/graphql");
+ client.Socket.Options.SetRequestHeader("Authorization", "Bearer ...");
+ });
+```
+
+You can also access the `IServiceProvider` with the following overload:
+
+```csharp
+services
+ .AddConferenceClient()
+ .ConfigureWebSocketClient((serviceProvider, client) =>
+ {
+ var token = serviceProvider.GetRequiredService().Token;
+ });
+```
+
+The second parameter of the `ConfigureWebSocketClient` method, can be used to access the `IWebSocketClientBuilder`
+
+```csharp
+services
+ .AddConferenceClient()
+ .ConfigureWebSocketClient(
+ (serviceProvider, client) =>
+ {
+ var token = serviceProvider.GetRequiredService().Token;
+ },
+ builder =>
+ builder.ConfigureConnectionInterceptor());
+```
+
+## WebSocketClientFactory
+
+If you prefer to use the `ServiceCollection` to configure your web socket, you can use the `AddWebSocketClient` method. Strawberry Shake generates a `ClientName` property, on each client. You can use this, to easily specify the correct name of the client.
+
+```csharp
+services
+ .AddWebSocketClient(
+ ConferenceClient.ClientName,
+ client => client.Uri =
+ new Uri("wss://workshop.chillicream.cloud/graphql/"));
+
+services.AddConferenceClient();
+```
+
+## IWebSocketClient
+
+On a `IWebSocketClient` you can configure the `Uri` of your endpoint. You can also directly set a `ISocketConnectionInterceptor` on the client, to intercept the connection and configure the initial payload. You do also have access to the underlying `ClientWebSocket` to configure headers or cookies.
+
+```csharp
+IWebSocketClient client;
+client.Uri = new Uri("wss://workshop.chillicream.cloud/graphql/");
+client.Socket.Options.SetRequestHeader("Authorization", "Bearer …");
+client.ConnectionInterceptor = new CustomConnectionInterceptor();
+```
+
+## Initial payload
+
+In JavaScript it is not possible to add headers to a web socket. Therefor many GraphQL server do not use HTTP headers for the authentication of web sockets. Instead, they send the authentication token with the first payload to the server.
+
+You can specify create this payload with a `ISocketConnectionInterceptor`
+
+```csharp
+public class CustomConnectionInterceptor
+ : ISocketConnectionInterceptor
+{
+ // the object returned by this method, will be included in the connection initialization message
+ public ValueTask