WireGuard by itself is bare. Currently it don't have a "proper" ("official") way to make custom transport for it. Thus if you have to do it, the task is no different than writing a UDP proxy.
But that UDP proxy is then an independent program, with no awareness on the states of the WireGuard instance, thus the proxy have to run in a very dumb/blind way. That's not ideal.
If you want to write a network proxy, it's the best for the proxy to know as much user intent as possible, so for example it knows which request should be retried, which should be given up as fast as possible if encountered a fault, and which request should just be rerouted to another server, etc.
Why is it best for the proxy to "know as much user intent as possible"? You can get that with WireGuard either way, but it's not at all clear to me that's true. We ran a rather huge deployment of WebSockets-encapsulated WireGuard, and I believe Tailscale has as well, and the fact that WireGuard was oblivious to it caused no problems I'm aware of.