Hello, I'm Maneshwar. I'm working on FreeDevTools online currently building *one place for all dev tools, cheat codes, and TLDRs* — a free, open-source hub where developers can quickly find and use tools without any hassle of searching all over the internet.
Debugging in Astro is mostly familiar territory if you’ve worked with web frameworks before, but there are important differences because Astro renders on the server by default.
This guide collects practical, real-world debugging tips so you can find problems faster and with less friction.
Where your console.log()
shows up
console.log()
is simple and effective — but where you put it matters in Astro.
- Frontmatter (server)
---
console.log('Hi! I\'m the server. This logs to the terminal where Astro is running.');
---
Anything in the frontmatter runs on the server and prints to the terminal running the Astro CLI.
-
<script>
in the component (client)
<script>
console.log('Hi! I\'m the client. This prints in the browser devtools console.');
</script>
Code in a <script>
tag (module by default) runs in the browser.
-
Framework components (React/Svelte/Vue)
These render server-side by default, so
console.log()
will usually appear in the terminal — but when the component is hydrated on the client (via aclient:
directive), logs may also appear in the browser console. This helps you compare server render vs hydrated client behavior.
Use the built-in <Debug />
component
Astro ships with a Debug
component that outputs values directly into your rendered HTML — great when you want to inspect data without switching between terminal and browser.
---
import { Debug } from 'astro:components';
const sum = (a, b) => a + b;
const answer = sum(2, 4);
---
<!-- All three are equivalent -->
<Debug answer={sum(2, 4)} />
<Debug {{answer: sum(2, 4)}} />
<Debug {answer} />
<Debug />
is particularly handy for templating issues and quick experiments where you need to see the shape of objects in the page source.
Common error messages and fixes
Cannot use import statement outside a module
- Cause:
<script>
tags in Astro are modules by default, but adding attributes likeis:inline
removes that default. - Fix: Add
type="module"
to the<script>
tag if you need to useimport
.
document
or window
is not defined`
- Cause: Server-side rendering.
document
andwindow
don't exist on the server. - Fixes:
- Move browser-only code into a
<script>
tag in the template (client). - In framework components, use lifecycle hooks (
useEffect
,onMount
) and hydrate with aclient:
directive (e.g.client:load
orclient:only
). - Check third-party packages — some require client-only execution.
- Move browser-only code into a
Expected a default export
- Cause: Importing or rendering an invalid component (or missing export).
- Fix: Verify import path, filename/extension, and that the component actually exports correctly. Reproduce in a minimal Astro starter if unsure.
Refused to execute inline script
(CSP)
- Cause: A strict Content Security Policy that blocks inline scripts (Astro emits inline script by default).
- Fixes:
- Add
script-src: 'unsafe-inline'
to CSP (not ideal). - Use an integration like
astro-shield
to generate safe CSP headers.
- Add
Common gotchas and quick checks
-
Component not rendering
- Ensure you imported the component and used the correct import path and file extension (.astro, .svelte, .vue, .mdx, etc.).
-
Component renders but is not interactive
- If you expect client interactivity, add a
client:
directive (e.g.client:load
,client:idle
,client:visible
) or useclient:only
when appropriate.
- If you expect client interactivity, add a
-
Cannot find package 'X'
- Some integrations (e.g.
@astrojs/react
) require installing peer dependencies likereact
andreact-dom
. - Example:
npm install @astrojs/react react react-dom
- Some integrations (e.g.
-
Yarn 2+ (Berry) issues
- Berry uses Plug'n'Play; set
nodeLinker: "node-modules"
in.yarnrc.yml
if you encounter issues.
- Berry uses Plug'n'Play; set
-
Monorepo dependency quirks
- Add Astro-related dependencies to the project
package.json
, and for some packages add them tovite.ssr.noExternal
inastro.config.mjs
.
- Add Astro-related dependencies to the project
-
Unexpected
<style>
inclusion- Astro bundles styles from any imported component present in the module graph — even if conditionally rendered and not present in final output.
Closing notes
Astro’s server-first model forces you to think intentionally about where code runs — and that distinction makes debugging clearer once you internalize it.
Use console.log()
in the right place, lean on <Debug />
for quick inspections, and keep minimal reproductions handy for tricky cases.
I’ve been building for FreeDevTools.
A collection of UI/UX-focused tools crafted to simplify workflows, save time, and reduce friction in searching tools/materials.
Any feedback or contributors are welcome!
It’s online, open-source, and ready for anyone to use.
👉 Check it out: FreeDevTools
⭐ Star it on GitHub: freedevtools
Top comments (0)