browser_only
is the ppx to exclude client code from the server build, making sure a library can run on both build targets.
For example, if you're using Webapi to query the DOM or using LocalStorage. This code should only run on the client, and there's no equivalent or fallback on the server, in order to compile and run successfully on the server, you can use browser_only
or switch%platform
.
The ppx expose a browser_only
attribute that can be used to discard a function or a value, and switch%platform
to conditionally execute code based on the platform.
Add server-reason-react.browser_ppx
into to your pps field under a dune stanzas (melange.emit, libraries or executable) in your dune files.
You would need to add it on both "server" and "client" dune files. Adding the -js
flag server-reason-react.browser_ppx -js
for the client and without for the server:
; server exectuable
(executable
(name server)
(preprocess
(pps server-reason-react.browser_ppx)))
; melange emitting JavaScript
(melange.emit
(target app)
(preprocess
(pps server-reason-react.browser_ppx -js)))
let%browser_only countDomNodes = (id) => {
let elements = Webapi.Element.querySelector("#" ++ id);
let arr_elements = Webapi.Element.toArray(elements);
Array.length(arr_elements);
};
The method tagged by browser_only
will keep the function untouched for the client build, but for the server build, will be transformed to a function that raises the exception Runtime.Impossible_in_ssr
.
If this function runs on the server, it will raise an exception, and the server will crash. In order to prevent this, you can use try
to catch the exception and provide a default behaviour/value.
Following with the example from above:
let%browser_only countDomNodes = (id) => {
let elements = Webapi.Element.querySelector("#" ++ id);
let arr_elements = Webapi.Element.toArray(elements);
Array.length(arr_elements);
}
let main = id =>
try(countDomNodes(id)) {
| _ => 0
};
switch%platform
allows to conditionally execute code based on the platform. There are some cases where you need to run a specific code only on the server or only on the client.
switch%platform (Runtime.platform) {
| Server => print_endline("This prints to the terminal")
| Client => Js.log("This prints to the console")
};