Usually it's stored in the app/browser, hopefully never on the server. You can also use extensions like nos2x or alby to protect your key from the app, or you can use NIP 46 signers like nsec.app or Amber to hold your own keys and sign remotely.
Thank you for the explanation. I'm looking at the NIP-46 doc and it's really a neat solution.