How to use HX-Redirect in HTMX frontend using FastAPI?
Asked Answered
V

1

2

I'm trying to redirect on the frontend after a login. I make a request from my htmx frontend like this

<form hx-post="/authenticate" hx-target= "#success" id="login-form">

  <div id="success" class="mb-2"></div>

 </div>
.......input fields and submit button.....
</form>

My authenticate endpoint looks like this

@router.post("/authenticate", response_class=HTMLResponse)
async def authenticate(request: Request, response: Response, email: str = Form(), password: str = Form()):

    ..........
    #auth logic#
    ............
    response.headers["HX-Redirect"] = "http://127.0.0.1:8000/"
    data = {
        "success": "Logged in successfully"
    }
    return web_config.templates.TemplateResponse("auth_success.html", {"request": request, "data": data})

I know the code works because auth_success.html is successfully swapped on the frontend but what I expect to happen next is for the browser to redirect to the homepage(http://127.0.0.1:8000/), but it doesn't happen.

My CORS settings are all correct

        allow_origins=origins,
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
        expose_headers=["*"],

NOTE: Using RedirectResponse wouldn't work because of how HTMX(not HTML) works. It'll only call the endpoint and swap it's response into <div id="success"></div> which is not a redirect.

Vitriform answered 3/1, 2023 at 11:30 Comment(4)
Does this answer your question? How to redirect the user back to the home page using FastAPI, after submitting an HTML form?Baalman
Related answers can be found here, here, as well as here, here and here.Baalman
@Chris, i already tried redirectresponse. It wouldn't work for my case specifically because of how htmx(not just hmtl) works. What this will do is to swap the result of redirectresponse(the template response) into the div with id "success" in my HTML markup and that's not what I want.Vitriform
Thanks @Chris. your last comment about assingning the the template response object to the response object was actually what worked.Vitriform
B
1

The reason for the redirection not taking place is due to the way you attempt adding the HX-Redirect header to the response. You are currently adding it to the Response object; however, since you are returning a TemplateResponse instead, the header is not added to the response you are actually returning. Hence, you should instead add the HX-Redirect header to the TemplateResponse, similar to the example below:

@router.post('/authenticate', response_class=HTMLResponse)
async def authenticate(request: Request, email: str = Form(), password: str = Form()):
    # ...
    
    data = {'msg': 'Logged in successfully'}
    response = templates.TemplateResponse('auth_success.html', {'request': request, 'data': data})
    response.headers['HX-Redirect'] = 'http://127.0.0.1:8000/'
    return response
Baalman answered 3/1, 2023 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.