I had a basic html and css with with vanila javascript which works with keyboard interactions and now transformed to astro but getiing error
document not defined and sugegsted to use client:only
I understand that Astro use SSR so it does not hyderate, but when apply client:load it gives the same error
here is sample code
Panel.astro
---
import "assets/styles/panel.css";
import { updatePanel} from "@/components/panel";
---
<label class="vertical" for="vertical">
<input type="radio" class="orientation" name="orientation" id="vertical" value="X">
</label>
components/panle.ts
const orientationPanel = document.querySelectorAll(".orientation");
const panel = document.querySelector(".panel");
const updatePanel = (num = 0) => {
const fragment = document.createDocumentFragment();
for (let i = 0; i < num; i++) {
const div = document.createElement("div");
div.classList.add("panel__cell");
div.textContent = String.fromCodePoint(65 + i); // A to Z
fragment.appendChild(div);
}
panel.innerHTML = "";
panel.appendChild(fragment);
};
const onChangePanel = (e: any) => {
changePanel(e.target.value);
updatePanel(Number(e.keyCode));
};
orientationPanel?.addEventListener("change", onChangePanel);
it throw error as below
[ERROR] document is not defined Hint:
Browser APIs are not available on the server.
If the code is in a framework component, try to access these objects after rendering using lifecycle methods
or use aclient:only
directive to make the component exclusively run on the client
.
so tries to add client:only which has below code
Navigation.astro
---
import "@/assets/styles/nav.css";
---
<nav class="nav">
<div class="nav--list">
<a class="link list--item" href="/panel" client:load><span>Panel</span></a>
</div>
</nav>
sidenote: when use client:load
then throw typescript error on the element
Type '{ children: any; class: string; href: string; "client:load": true; }' is not assignable to type 'AnchorHTMLAttributes'.
Property 'client:load' does not exist on type 'AnchorHTMLAttributes'.ts(2322)
it might be because using <a>
so create an Astro component
Link.astro
---
const { href, name } = Astro.props
---
<a class="link list--item" href={href}><span>{name}</span></a>
and use it in Navigation.astro
<Link href="panel" name="panel" client:load/>
but still throwing same
document is not defined
Hint:
Browser APIs are not available on the server.