Simple Debug Panel for Static Sites
A lightweight debug panel for static sites built for Jekyll, Eleventy, Hugo, and other static site generators. Inspired by Laravel's debug bar, Snail Trail provides real-time performance metrics, resource analysis, and development insightsโall accessible via a sleek pull-up panel.
- Performance Monitoring - TTFB, FCP, LCP, Resource Timing
- Resource Analysis - Track scripts,
stylesheets,imageswith sizes and load times - Environment Info -
Viewport,user agent,connection type,color scheme - JavaScript State -
LocalStorage,SessionStorage,cookies, eventlisteners - DOM Analysis - Node count, depth, accessibility checks (missing alt tags)
- Console Interception - Capture and display console messages within the panel
- Build Information - Display build timestamps, git hashes, environment
- Keyboard Shortcut - Toggle with
Ctrl+Shift+D - Mobile Friendly - Debug on any device without DevTools
- Customizable - Drag to resize, persistent state
- logcad intergration, catches dispatched log messages from
logd - Simple usage:
localstoragevariable, window__BUILD_TIMESTAMP__,__BUILD_HASH__,__BUILD_ENV__ - UI memory: Remember UI state:
open,close,height
Ctrl+Shift+D- Toggle debug panel visibility
๐ Option 1: Direct Include auto load
-
Link script file local or from cdn:
<!-- Add before closing </body> tag --> <script src="path/to/snailtrail-debugger.js"></script> <!-or-> // PENDING <-------
-
Basic Usage Vanilla JS, just set the localstorage varriable
__snail_debugtotrue;// In browser console or your script set `__snail_debug` to `true` localStorage.__snail_debug = 'true'; // if you've linked debugger.js as standard script, it will auto run initialization automatically // can always set a button to do this // Looks for // - `__snail_debug` in LocalStorage // - `__BUILD_TIMESTAMP__`, `__BUILD_HASH__`, `__BUILD_ENV__` in window
๐ Option 2: ES Module ( type="module" )
-
Install snail trail debugger
npm install snailtrail-debugger # use npm # or via cdn: jsdelivr <script src="https://cdn.jsdelivr.net/npm/snailtrail-debugger@latest/dist/snailtrail.js"></script>
-
Import requred functions
import { SnailTrailDebugger, initSnailTrailDebugger } from 'snailtrail-debugger';
-
Modern Usage with ES6 Enable the debugger:
// In browser console or your script set `__snail_debug` to `true` // Initialize the debugger const SnailTrailDebugger = new SnailTrailDebugger({ storageKey: '__snail_debug' parnelId: 'debug-panel' buildInfo: { timestamp: '2024-11-14 10:30:00', hash: 'abc123def456', env: 'production' } }); // call init function to setup event listners initSnailTrailDebugger();
<!-- _includes/debug.html -->
<script>
window.__BUILD_TIMESTAMP__ = '{{ site.time | date: "%Y-%m-%d %H:%M:%S" }}';
window.__BUILD_HASH__ = '{{ site.github.build_revision }}';
window.__BUILD_ENV__ = '{{ jekyll.environment }}';
</script>
<script src="{{ '/assets/js/snail-trail-debugger.js' | relative_url }}"></script>
<!-- In your layout -->
{% if jekyll.environment == "development" %}
{% include debug.html %}
{% endif %}// .eleventy.js
eleventyConfig.addShortcode("buildInfo", function() {
return `
<script>
window.__BUILD_TIMESTAMP__ = '${new Date().toISOString()}';
window.__BUILD_HASH__ = '${process.env.GIT_COMMIT || 'local'}';
window.__BUILD_ENV__ = '${process.env.ELEVENTY_ENV || 'development'}';
</script>
`;
});<!-- _includes/layouts/base.njk -->
{% if env == "development" %}
{% buildInfo %}
<script src="/assets/js/snail-trail-debugger.js"></script>
{% endif %}<!-- layout๐ธ s/partials/debug.html -->
<script>
window.__BUILD_TIMESTAMP__ = '{{ now.Format "2006-01-02 15:04:05" }}';
window.__BUILD_HASH__ = '{{ getenv "GIT_COMMIT" }}';
window.__BUILD_ENV__ = '{{ hugo.Environment }}';
</script>
<script src="{{ "js/snail-trail-debugger.js" | relURL }}"></script>
<!-- In your baseof.html -->
{{ if eq hugo.Environment "development" }}
{{ partial "debug.html" . }}
{{ end }}- Page load time
- Time to First Byte (TTFB)
- First Contentful Paint (FCP)
- Largest Contentful Paint (LCP)
- DNS lookup & TCP connection times
- Top 5 slowest resources
- Total page weight
- Failed resources count
- All loaded scripts with sizes and load times
- All stylesheets with metrics
- Images with dimensions and sizes
- Current URL
- User agent
- Viewport dimensions
- Screen resolution & pixel ratio
- Color scheme preference (dark/light)
- Connection type (4G, WiFi, etc.)
- LocalStorage size
- SessionStorage size
- Cookies (names only)
- Active event listeners estimate
- Real-time console log capture (last 20 messages)
- Total DOM nodes
- Maximum DOM depth
- Iframe count
- Forms count
- Images without alt attributes
- Internal vs external links
- Build timestamp
- Git commit hash
- Environment (dev/staging/prod)
- Build Environment
The debugger includes minimal default styles. You can customize by targeting these classes:
.debug-panel { /* Main container */ }
.debug-handle { /* Drag handle */ }
.debug-controls { /* Top control bar */ }
.debug-tabs { /* Tab buttons */ }
.debug-content { /* Content area */ }
.tab-content { /* Individual tab panels */ }
.debug-list { /* List items */ }// Refresh all data
window.snailDebugger.refresh();
// Destroy and remove panel
window.snailDebugger.destroy();
// Access console log programmatically
console.log(window.snailDebugger.consoleLog);- Local Development - Monitor performance during development
- Client Demos - Show technical metrics to stakeholders
- Mobile Testing - Debug without remote DevTools
- Performance Audits - Quick performance overview
- Accessibility Checks - Find images missing alt attributes
- Build Verification - Confirm correct build artifacts deployed
- Only enable in development - Use environment checks in your templates
- Inject build info - Makes debugging production issues easier
- Use keyboard shortcut - Quick toggle without scrolling
- Monitor console tab - Catch JavaScript errors early
- Check failed resources - Identify broken asset links
The debugger only collects client-side data that's already accessible through the browser. It does not:
- Send data to external servers
- Access sensitive cookie values
- Expose server-side information
- Store data beyond LocalStorage
However, always disable in production unless needed for specific debugging scenarios.
Panel doesn't appear:
- Check
localStorage.__snail_debugis set to'true'(string, not boolean) - Ensure script is loaded after DOM is ready
- Check browser console for JavaScript errors
Build info shows "Not configured":
- Verify build variables are being injected
- Check
window.__BUILD_TIMESTAMP__etc. are defined before debugger initializes
Performance metrics show N/A:
- Some metrics require HTTPS (like connection type)
- LCP requires user interaction on some browsers
- Wait for full page load before checking
MIT License - feel free to use in personal and commercial projects.
- Laravel Debug Bar by Taylor Otwell
- Symfony Web Debug Toolbar by Fabien Potencier
- Browser DevTools by Google
Contributions welcome! Please feel free to submit a Pull Request.
- ๐ Report a bug
- ๐ก Request a feature
- ๐ Documentation
Made with ๐ and โ for the static site community