BookStack is primarily server-side-rendered, but it uses JavaScript sparingly to drive any required dynamic elements. Most JavaScript is applied via a custom, and very thin, component interface to keep code organised and somewhat reusable.
JavaScript source code can be found in the `resources/js` directory. This gets bundled and transformed by `esbuild`, ending up in the `public/dist` folder for browser use. Read the [Development > "Building CSS & JavaScript Assets"](development.md#building-css-&-javascript-assets) documentation for details on this process.
## Components
This section details the format for JavaScript components in BookStack. This is a really simple class-based setup with a few helpers provided.
### Defining a Component in JS
```js
class Dropdown {
setup() {
this.container = this.$el;
this.menu = this.$refs.menu;
this.toggles = this.$manyRefs.toggle;
this.speed = parseInt(this.$opts.speed);
}
}
```
All usage of $refs, $manyRefs and $opts should be done at the top of the `setup` function so any requirements can be easily seen.
Once defined, the component has to be registered for use. This is done in the `resources/js/components/index.js` file by defining an additional export, following the pattern of other components.
You can then access the span element as `this.$refs.toggle` in your component.
Multiple elements of the same reference name can be accessed via a `this.$manyRefs` property within your component. For example, all the buttons in the below example could be accessed via `this.$manyRefs.buttons`.
```html
<divcomponent="list">
<buttonrefs="list@button">Click here</button>
<buttonrefs="list@button">No, Click here</button>
<buttonrefs="list@button">This button is better</button>
A component has the below shown properties & methods available for use. As mentioned above, most of these should be used within the `setup()` function to make the requirements/dependencies of the component clear.