Chris
Chris

Reputation: 107

HTMX - Read URL Search Params / Query String and pass into fetch request

Very simple landing page, thought it would be a good place to start playing with HTMX. The objective is really simple:

Landing page with a query string in the URL. onLoad it fires a request to server, sending the params from the query string along. Server does its thing and sends back a success or error HTML snippet.

I do not need a button or form, all the info I need comes from the queryString. Users get redirected to this page from another app.

Question 1: How can I get the searchParms into the hx-get?

I must be missing something but I couldn't find any other way than using some JS.

HTMX:

<div
  hx-get="https://jsonplaceholder.typicode.com/users"
  hx-vals="js:{id: id, comment: comment}"
  hx-trigger="load"
  hx-target="#result"
></div>
<div id="result" class="m-8 p-8 bg-slate-200">Loading…</div>

JS:

function getParams() {
  // const urlParams = new URLSearchParams(window.location.search);
  const urlParams = new URLSearchParams('id=4&comment=25');
  const id = urlParams.get('id');
  const comment = urlParams.get('comment');

  return { id: id, comment: comment };
}

const { id, comment } = getParams();

Sample:

https://stackblitz.com/edit/stackblitz-starters-9z2kgg?file=index.html

Question 2: I would have thought the entire idea behind HTMX was that for the very largest part I don't need to write the JS. Or is this a case where I would look at Hyperscript?

Question 3: hx-trigger="load" on a div looks odd to me, surely that's not exactly how it's thought to be done?

In production I would of course do the entire parsing of the queryString and writing the HTML response in the backend - but for that I need to get the params from the queryString back there first. What am I missing?

Upvotes: 2

Views: 3922

Answers (2)

user1544428
user1544428

Reputation: 150

If you have access to the backend and can use hx-post, you can send what you need like this:

<button id="btnModal" type="button" hx-post="/api/htmx/test/update/modal" hx-vals='js:{blogId: getblogId()}' hx-target="body" hx-swap="beforeend" style="visibility:hidden;" >Open a Modal</button>

Where getblogId() is a vanilla javascript function to get the id to send, however you may need to do that.

If you have to use hx-get, it will append the name and value of the sending element to the url by default. It's a little hacky, but I made a test page to send a url parameter to a C# WebAPI on page load:

// http://localhost:53455/admin/apitest/fromurl.html?param=1234654

<button id="btnModal" name="modalm" type="button" hx-get="/api/htmx/test/update/modal2/" hx-target="body" hx-swap="beforeend" style="visibility:hidden;">Open a Modal</button>
<script>

    window.addEventListener("load", function () {
        openModal();
    });

    function openModal() {
        var modal = document.getElementById("btnModal");
        modal.value = getParams();
        modal.click();
    }

    function getParams() {
        const urlParams = new URLSearchParams(window.location.search);
        const id = urlParams.get('param');

        return id;
    }

</script>

That's just using a hidden button and vanilla javascript to change the button's value and programmatically clicking it on page load.

Using that url and code, my request on the backend was:

{Method: GET, RequestUri: 'http://localhost:53455/api/htmx/test/update/modal2/?modalm=1234654', Version: 1.1,

I know you said you don't need a button, but this could be adapted to other controls. I have some similar code working well using one hidden button and javascript, and other events just "click" this button and send the id to the backend.

Upvotes: 0

Chris
Chris

Reputation: 107

After digging into this I would like to present a more elegant solution:

HTMX adds additional headers to HTTP request headers. You can inspect these and tailor your response. In particular the HX-Current-URL is of interest here.

If you don't serve from or have access to your web server directly and interact with and/or have access to an endpoint you can read the request url from this additional header HTMX appends:

const requestUrl = request.headers.get("HX-Current-URL")!;

And you can then extract the query string, in this example id:

const postId = new URL(requestUrl).searchParams.get("id");

And then append the id to your fetch call, e.g.:

const res = await fetch(
  `https://jsonplaceholder.typicode.com/posts/${postId}`
);

This way on page load you can feed the query string variables from your current URL into a fetch call to any API.

<div hx-get="/api/getPost" hx-trigger="load" hx-target="#result"></div>
<div id="result" class="m-8 p-8 bg-slate-200">Loading…</div>

Upvotes: 1

Related Questions