For sending debugging information alongside XMLHttpRequests.

Download Chrome Extension View source on GitHub

Why use DebugR?

When you're developing a WebApp or other ajax heavy webpage, a lot of the backend code is executed inside those requests. Apps like trello for example just have a empty <div id="content"></div> on the page.

Some Webframeworks (like CakePHP) can display a querylog on the page. But these logs are now rendered useless because all the queries are hidden behind json responses. *1

This is where DebugR enters the scene. DebugR enables sending meta-data alongside the json/xml/data via "DebugR-*" HTTP headers. This isn't new, FirePHP does this since 2007.
Although DebugR uses the same trick as FirePHP for its transport (HTTP headers). FirePHP handles the data in its browser plugin while DebugR just passes the data to javascript via window.postMessage().
This fundamental diffence allow webframeworks to handle the data in any way they like.

The Sledgehammer Framework for example, uses a "statusbar" message to send a querylog (formatted in plain html) and adds the html to its statusbar element. Creating a statusbar that updates in realtime when new ajax responses are being processed.

Supported browsers

Although DebugR initialy started as a Chrome Extension, it now has a pure javascript implementation which is compatible with: Google Chrome, Apple Safari and Mozilla Firefox

Sending DebugR messages

Examples are in PHP, but DebugR works with any language

if (isset($_SERVER['HTTP_DEBUGR'])) { // Only send headers when DebugR is enabled
  // Send a message alongside the request.
  header('DebugR: '.base64_encode('Hello DebugR'));
  // Append a unique label to send multiple messages.
  header('DebugR-my-first-label: '.base64_encode('Moarr information'));
  // Sending multiple messages with the same label, by appending "." + number:
  header('DebugR-my-first-label.1: '.base64_encode('Moarr information'));

  // For very large messages, you should send the message in chunks (Detected by the ".chunk0" suffix).
  // Restriction on the maximum size for a single HTTP header (Max 4Kib for nginx 8KiB for Apache)
  $chunks = str_split(base64_encode($largeString), (4 * 1024)); //
  foreach ($chunks as $index => $chunk) {
    header('DebugR-largeString.chunk'.$index.': '.$chunk);


window.addEventListener('message', function (e) {
  if ( {
}, false);
// Signal the extension that the eventlistener is active.
document.documentElement.setAttribute('data-debugR', 'active');


Example debugr.js usage

<script src="debugr.js"><script>
  debugR(function(message, details) {

Using debugr.js via its asynchronous api

var debugR = debugR || [];
debugR.push(function (message, details) {

 .. other scripts and html ...

(function () {
  var el = document.createElement('script'); el.type = 'text/javascript'; el.async = true;
  el.src = '/js/debugr.js';
  var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(el, s);


*1: The Symfony Framework has an toolbar which links to a profiler page which allows you inspect querylogs for all requests. It's not "useless" without DebugR, but DebugR could make the toolbar more interactive.