Encode Diagrams
When using GET requests, your diagram must be encoded in the URL using a deflate + base64 algorithm. On this page you will learn how to encode a diagram using:
| To decode a diagram (e.g. from Kroki log message) we recommend using Kroki CLI or one of the decoders listed on the Third Party Tools page. | 
Node.js
To compress our diagram with deflate algorithm, we are going to use pakoβββa high speed zlib port to JavaScript.
Once pako is installed, you can use the deflate method:
const pako = require('pako')
const diagramSource = `digraph G {
  Hello->World
}`
const data = Buffer.from(diagramSource, 'utf8') 
const compressed = pako.deflate(data, { level: 9 }) 
const result = Buffer.from(compressed)
  .toString('base64') 
  .replace(/\+/g, '-').replace(/\//g, '_') 
console.log(result)| 1 | Create a Bufferfrom the diagram source using the default UTF-8 encoding | 
| 2 | Compress data with deflate algorithm using a compression level of 9 (best compression). | 
| 3 | Create a Bufferfrom the compressed data and encode to Base64 | 
| 4 | Replace +and/characters to make it "URL safe" | 
JavaScript
We recommend encoding your diagram as UTF-8.
To do so, we can use TextEncoder:
new TextEncoder('utf-8').encode(diagramSource)Unfortunately TextEncoder is not yet available on all browsers.
To workaround this issue, we can define a function to encode our diagram:
function textEncode(str) {
  if (window.TextEncoder) {
    return new TextEncoder('utf-8').encode(str);
  }
  var utf8 = unescape(encodeURIComponent(str));
  var result = new Uint8Array(utf8.length);
  for (var i = 0; i < utf8.length; i++) {
    result[i] = utf8.charCodeAt(i);
  }
  return result;
}The above code will use TextEncoder if itβs available and otherwise it will use a fallback implementation.
Now that our diagram is encoded as UTF-8 in a Uint8Array, we can use pako to compress it.
As a reminder, pako is a high speed zlib port to JavaScript:
<script src="https://unpkg.com/pako@1.0.10/dist/pako_deflate.min.js"></script>To compress our diagram diagram we are going to use the deflate method provided by pako:
var diagramSource = 'digraph G { Hello->World }'
var data = textEncode(diagramSource) 
var compressed = pako.deflate(data, { level: 9, to: 'string' }) 
var result = btoa(compressed) 
  .replace(/\+/g, '-').replace(/\//g, '_') 
console.log(result)| 1 | Encode the diagram as UTF8 in a Uint8Array(using thetextEncodefunction declared above) | 
| 2 | Compress data with deflate algorithm using a compression level of 9 (best compression). pakois available as a global variable. | 
| 3 | Encode to Base64 using btoaglobal function | 
| 4 | Replace +and/characters to make it "URL safe" | 
Python
import sys;
import base64;
import zlib;
print(base64.urlsafe_b64encode(zlib.compress(sys.stdin.read(), 9)))Java
package main;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.zip.Deflater;
public class Encode {
  public static byte[] encode(String decoded) throws IOException {
    return Base64.getUrlEncoder().encode(compress(decoded.getBytes()));
  }
  private static byte[] compress(byte[] source) throws IOException {
    Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION);
    deflater.setInput(source);
    deflater.finish();
    byte[] buffer = new byte[2048];
    int compressedLength = deflater.deflate(buffer);
    byte[] result = new byte[compressedLength];
    System.arraycopy(buffer, 0, result, 0, compressedLength);
    return result;
  }
}Kotlin
package main
import java.util.Base64
import java.util.zip.Deflater
object Encode {
  fun encode(decoded: String): String =
    String(Base64.getUrlEncoder().encode(compress(decoded.toByteArray())), Charsets.UTF_8)
  private fun compress(source: ByteArray): ByteArray {
    val deflater = Deflater()
    deflater.setInput(source)
    deflater.finish()
    val bytesCompressed = ByteArray(Short.MAX_VALUE.toInt())
    val numberOfBytesAfterCompression = deflater.deflate(bytesCompressed)
    val returnValues = ByteArray(numberOfBytesAfterCompression)
    System.arraycopy(bytesCompressed, 0, returnValues, 0, numberOfBytesAfterCompression)
    return returnValues
  }
}Go
package main
import (
	"bytes"
	"compress/zlib"
	"encoding/base64"
	"github.com/pkg/errors"
)
// Encode takes a string and returns an encoded string in deflate + base64 format
func Encode(input string) (string, error) {
	var buffer bytes.Buffer
	writer, err := zlib.NewWriterLevel(&buffer, 9)
	if err != nil {
		return "", errors.Wrap(err, "fail to create the writer")
	}
	_, err = writer.Write([]byte(input))
	writer.Close()
	if err != nil {
		return "", errors.Wrap(err, "fail to create the payload")
	}
	result := base64.URLEncoding.EncodeToString(buffer.Bytes())
	return result, nil
}PHP
<?php
function base64url_encode($data) {
  return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function encode($data) {
  return base64url_encode(gzcompress($data));
}Tcl
# assuming the diagram code is stored in the variable named `diagramSource`:
puts [string map {+ - / _} [binary encode base64 [zlib compress $diagramSource]]]Also, see the Tcl package dia2kroki which has procedures to both decode and encode the diagram source code and a GUI to create diagrams with a live preview.
C#
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
class Program
{
    static byte[] Deflate(byte[] data, CompressionLevel? level = null)
    {
        using (var memStream = new MemoryStream())
        {
#if NET6_0_OR_GREATER
            using(ZLibStream zlibStream = level.HasValue ? new(memStream, level.Value, true) : new(memStream, CompressionMode.Compress, true))
            {
                zlibStream.Write(data);
            }
#else
            // Reference: https://yal.cc/cs-deflatestream-zlib/#code
            // write header:
            memStream.WriteByte(0x78);
            memStream.WriteByte(level switch
            {
                CompressionLevel.NoCompression or CompressionLevel.Fastest => 0x01,
                CompressionLevel.Optimal => 0x0A,
                _ => 0x9C,
            });
            // write compressed data (with Deflate headers):
            using (DeflateStream dflStream = level.HasValue ? new(memStream, level.Value, true) : new(memStream, CompressionMode.Compress, true))
            {
                dflStream.Write(data, 0, data.Length);
            }
            // compute Adler-32:
            uint a1 = 1, a2 = 0;
            foreach (byte b in data)
            {
                a1 = (a1 + b) % 65521;
                a2 = (a2 + a1) % 65521;
            }
            memStream.WriteByte((byte)(a2 >> 8));
            memStream.WriteByte((byte)a2);
            memStream.WriteByte((byte)(a1 >> 8));
            memStream.WriteByte((byte)a1);
#endif
            return memStream.ToArray();
        }
        
    }
    public static void Main(string[] args)
    {
        var compressedBytes = Deflate(Encoding.UTF8.GetBytes("digraph G {Hello->World}"));
#if NET9_0_OR_GREATER
        // You can use this in previous version of .NET  with Microsoft.Bcl.Memory package
        var encodedOutput = System.Buffers.Text.Base64Url.EncodeToString(compressedBytes);
#else
        var encodedOutput = Convert.ToBase64String(compressedBytes).Replace('+', '-').Replace('/', '_');
#endif
        Console.WriteLine($"https://kroki.io/graphviz/svg/{encodedOutput}");
    }
}| Please note that we cannot use we cannot use System.IO.Compression.DeflateStreambecause it does not include ZLIB header/trailer.
To learn more, please read: yal.cc/cs-deflatestream-zlib/#code |