Recently, I’ve been diving deep into Nuxt, and the experience has been fantastic. As a “Full-Stack Vue Framework,” it handles a lot of the heavy lifting, but one classic pain point remains: data visibility.
If you come from the Laravel ecosystem, you’re likely spoiled by dump(), dd(), or the powerhouse that is Laravel Ray. These tools provide instant, beautiful clarity into your data structures.
In the JavaScript world, we often fall back on console.log. While it’s a reliable old friend, it has a frustrating habit of truncating deeply nested objects into a useless [Object] string when viewed in the terminal during SSR (Server-Side Rendering).
Introducing useDump
To bridge this gap, I created useDump. It’s a simple composable designed to give you “Laravel-style” visibility without the terminal headaches.
- On the Server: It utilizes Node’s
util.inspectto render colorized, infinitely deep object trees directly in your terminal. - On the Client: It gracefully falls back to the standard browser console.
The Implementation
This composable leverages Nuxt’s built-in environment awareness. By using a dynamic import, we ensure that Node-specific modules never bloat your client-side bundle.
export const useDump = async (...args: any[]) => {
// 1. Safety first: strictly for local development
if (process.env.NODE_ENV !== "development") return;
if (import.meta.server) {
// Dynamically import Node's util module only on the server
const { inspect } = await import("node:util");
args.forEach((arg) => {
console.log(inspect(arg, {
colors: true,
depth: null,
showProxy: true
}));
});
} else {
// Standard logging for the browser console
console.log(...args);
}
};
Why use this?
1. Terminal Clarity
No more guessing what’s inside a nested API response. By setting depth: null, useDump forces the terminal to print every single leaf of your data tree.
2. Tree-Shaking Friendly
Because we use import.meta.server and a dynamic await import(), the node:util dependency is completely stripped from the code sent to the user’s browser.
3. Production Stealth
The NODE_ENV check acts as a kill-switch. You can leave your debug statements in place during a frantic dev session without worrying about leaking sensitive state or cluttering logs in your production environment.
Usage Example
You can use it exactly like a standard log, anywhere in your Vue components:
<script setup>
const { data: user } = await useAsyncData('user', () => $fetch('/api/user'))
// On the server, this outputs a beautiful, color-coded tree.
// On the client, it appears as a standard interactive object.
useDump('User Debug:', user.value)
</script>
Final Thoughts
useDump is a tiny addition to your utility folder, but it significantly reduces the friction of SSR development. It brings a slice of that world-class Laravel developer experience into the Nuxt ecosystem, helping you catch data mismatches before they ever hit the browser.