hx-push-url doesn’t work properly on device back button click

See original GitHub issue

I am trying to integrate Htmx with django and achieve single page application behaviour. I am rewritting Djangoproject.com poll app with htmx. When I click on detail page link, content loads, htmx push a new url in address bar. When I press back button, it took me to index page perfectly for the first time, after that if I again go to detail page and click back button, url shows of the index, but index content doesn’t load, content remains same as detail page. Here is my code -

views.py

def index(request):
    latest_question_list = Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    if request.headers.get("Hx-Request") is not None:
        return render(request, 'main/index/index.html', context)
    else:
        return render(request, 'main/index/index-full.html', context)
    
    
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    print(request.headers.get("Hx-Request"))
    if request.headers.get("Hx-Request") is not None:
        return render(request, 'main/detail/detail.html', {'question': question})
    else:
        return render(request, 'main/detail/detail-full.html', {'question': question})
    
index.html

<div id="index" class="">

    {% if latest_question_list %}
    <ul>
        {% for question in latest_question_list %}
        <li><div class="has-text-link" hx-get="{% url 'main:detail' question.id %}" hx-push-url="true" hx-target="#index" hx-swap="outerHTML">{{ question.question_text }}</div></li>
        {% endfor %}
    </ul>
    {% else %}
    <p>
        No polls are available.
    </p>
    {% endif %}

</div>

index-full.html

{% extends 'base.html' %}
{% block content %}
{% include 'main/index/index.html' %}
{% endblock content %}
detail.html

<div id="detail" class="">

    <form action="{% url 'main:vote' question.id %}" method="post">
        {% csrf_token %}
        <fieldset>
            <legend><h1>{{ question.question_text }}</h1></legend>
            {% if error_message %}<p>
                <strong>{{ error_message }}</strong>
            </p>
            {% endif %}
            {% for choice in question.choice_set.all %}
            <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
            <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
            {% endfor %}
        </fieldset>
        <input type="submit" value="Vote">
    </form>

</div>


detail-full.html

{% extends 'base.html' %}
{% block content %}
{% include 'main/detail/detail.html %}
{% endblock content %}

I found no error in browser console, no error in terminal

Now, I know I can put a back button in detail page that can took me to index page. But user won’t use that, they will just use the back button on their device. Note- I am on Android and talking about the back button in mobile phones

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:4
  • Comments:24 (13 by maintainers)

github_iconTop GitHub Comments

3reactions
David-Guillotcommented, Apr 17, 2022

Wow @gone nice catch!! Just tested importing of htmx.js from <head> instead of <body>, the issue is… gone 😉 . Let’s see what the best fix is 👍

2reactions
gonecommented, Apr 16, 2022

Just did a debug of this, and in the bottle example the error is coming from reloading htmx multiple times. It looks like on the reload of the cached version the currentPathForHistory is reset when it loads.

You can fix the bottle example by EITHER setting currentPathForHistory in the htmx source to window.currentPathForHistory (making it a global) or by moving the htmx load to the head like so:

  return bottle.template('''
   <html>
   <head>
       <script src="/static/htmx.js"></script>
   </head>
       <body>
           <b>click test, go back, click test again and notice you can't come back!</b>
           <div id="work_area">
               <div hx-target="#work_area">
                   <button
                   hx-get="/test/partial"
                   hx-push-url="/app/test">test</button>
               </div>
           </div>
       </body>
   </html>
   ''')

Another example of multiple initialization is the loading styling being applied multiple times. @David-Guillot I’m pretty sure this is the same case for the bug you’re seeing because after clicking through a couple of your hubs I can see in the header multiple instances of:

<style> .htmx-indicator{opacity:0;transition: opacity 200ms ease-in;} .htmx-request .htmx-indicator{opacity:1} .htmx-request.htmx-indicator{opacity:1} </style>

which makes me think you are also reloading htmx multiple times.

I think the workaround right now is moving htmx to your header - @1cg should the long term fix be having htmx notice it’s already been loaded and do nothing?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Hx-push-url doesn't work on back button click - Stack Overflow
When I click on detail page link, content loads, htmx push a new url in address bar. When I press back button, it...
Read more >
Preventing going back - React Navigation
Sometimes you may want to prevent the user from leaving a screen, for example, if there are unsaved changes, you might want to...
Read more >
Back button not working - Hotwire Discussion
Hello,. I have a page with a URL of /cars . I have some onpage live filters on this page and this uses...
Read more >
Tasks and the back stack | Android Developers
Note: Although the activity starts in a new task, the Back button and gesture still return the user to the previous activity. "singleInstance"...
Read more >
Angular Navigation: How Routing & Redirects Work in Angular ...
When our app loads, the router kicks things off by reading the URL the user is ... When we press the back button,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found