JavaScript is currently the default for interaction on web pages. Just because the page loads JavaScript it does not limit you to using JavaScript to write it.
The simple option is just to write JavaScript. This works an is the common approach.
The next step is to use Babel to transpile various extensions into JavaScript. This allows the use of language features that the browsers don’t yet support. Hopefully the near future loss of support of Internet Explorer 11 will allow this process to become easier. This is the typical option for React. This allows non-javascript components to be translated.
The next option is to move to Typescript. This is a backwards compatible language that adds some structure to JavaScript. This makes refactoring easier and adds some type information. This only exists at compile time. This is the technique used by most Angular applications.
There is a further option to move to other languages that compile to JavaScript. Here I am going to consider Elm, but other options exist (PureScript, Gleam). Elm is specifically designed for frontend applications. It’s a strongly typed functional language that makes strong claims about eliminating runtime errors. It has its own model based UI tools. It won’t eliminate logic errors but will work hard to give you it’s famously useful error messages.
Elm uses expressions rather than statements. This means that you always need an else if when you use if. Expressions always return something. It is a compile error to omit this. The language also has strong opinions on tab Vs spaces, as a tab in code whitespace will give a compile error. Lists need to be of a uniform type. Tuples can only have 2 or 3 elements (this constraint will greatly simplify APIs).