Is there a way for a shader to differentiate between viewport render and F12 final render?
Currently this solution relies on using an alpha version of the software (download  2.93 here) but it is pretty straightforward. Don't use for production until it is officially released.
Also, it seems it only works for Cycles if you are using a Windows OS.
Add a Geometry Nodes modifier to your object.
Plug an Attribute Fill node between the input and output. Change the Attribute name and remember it. Set the type to Color.
Plug the new Is Viewport node into the value. See the docs.

Add a material to your object, and add an Attribute node. See the docs.
Set the attribute name exactly as in the geometry node modifier. Plug the Color into your shader tree as you see fit. You may need to toggle between Material Preview and Render view to see the effect update.
This setup will render as White in the viewport, and as Black in the F12 rendered view :

Render Result :