Spend all week struggling with the same. Basically you have to use browsers' window.location.replace and initialize the location via Python from your function.
Let say you are here: http://www.mycoolapp.com/old_location in the html you place the JavaScript at the bottom before </body>: relocation_url = "http://www.mycoolapp.com/old_location" window.location.replace({{=relocation_url}}) When you want to redirect and the new html to replace the old one: you initialize: relocation_url = "http://www.mycoolapp.com/new_location" When the browser loads the page, close to the </body> (end of page) it sees actually window.location.replace ("http://www.mycoolapp.com/new_location") And it will reload the page with the new location in the browser bar and also the new html. If you use just the web2py redirect, it loads the html but you see the old url in the browser address bar. If the new page is a form, you fill out the form, hit the Submit button and nothing happens because the browser sees the old address bar. Struggled all week with that and only solution I found is that. Good luck and give back to community ;)