Here's a one line solution. Put this in your `functions.php` file: ```php add_action( 'template_redirect', function () { ob_start(); } ); ``` `ob_start()` begins output buffering, when the `template_redirect` actions are completed, and nothing has been sent to the browser. That means `wp_redirect()` works from anywhere: ```php wp_redirect( $url ); exit; ``` including in a shortcode. If the script terminates normally, without an exit, the buffer is automatically flushed and the whole page is sent at that time. Cheeky ... but it seems to work for me.