Skip to content

Proposal: {{urls.current}} to reference the current URL that the user is visiting within handlebars, inclusive of query params. #344

@34638a

Description

@34638a

Hi BC,
Not submitting this as a PR because I honestly don't even have a slight idea as to how to begin implementing this due to 0 working knowledge of the behind the scenes working of the rendering engine, or if this is even possible with the current rendering engine.

Proposed spec:

Under the existing {{urls}} object which is already present within the context of every page, I would propose the the following entry be added with the following structure:

{
    ...,
    "urls": {
        ...,
        "current": {
            "url": "https://example.com",
            "path": "/example/path",
            "query": {
                "key1": [],
                "key2": ["value1", "value2"],
                "key3": ["value3"],
                ...
            }
        }
    }
}

Why?

With this proposal, within the context of pre-rendering the content of the page can be dynamically modified and additional information can be gleamed about the state of the client application without the need to inject context post load.

This can be useful for pre-filling additional context for use in accessibility or user preferences, and provide a useful way to inject custom content relevant to the user request (eg. /kickback?ref=my-local-cafe would provide context that could be used to render a image of the kickback recipient logo and name).

This can also be useful for page widgets provided to the context. A example could be a support / chat application such as LiveChat or TawkTo, where they could render a different widget as a part of the initial page load dependant on the path. The contact us page could override the contact form with a form to directly link to the support page for instance by rendering a support widget instead.

Example:

During search, if you wanted to preserve the previous search in a "No-JS" environment (such as a terminal or otherwise bot friendly environment), this is the current way I am doing it:

{{! inputs
    - url: string
    - assign: string
}}

{{! url is passed from the current page in the pagination links object. }}
{{! example url: (lookup (lookup pagination.category.links pagination.category.current) "url") }}
{{! example url: /category-page-example/?page=1&q=test }}

{{! for the example we store the result in (assignVar "temp") }}

{{assignVar assign " "}}
{{!log url}}
{{!log assign}}
{{#with (urlParse (default url "/"))}}
    {{#each (split this.query "&")}}
        {{#with (split this "=")}}
            {{assignVar ../../../assign (multiConcat (getVar ../../../assign) "\"" this.[0] "\":\"" this.[1] "\",")}}
        {{/with}}
    {{/each}}
    {{assignVar ../assign (multiConcat "{\"href\":\"" this.href "\",\"path\":\"" this.pathname "\",\"query\":{\"" (chop (getVar ../assign)) "\"}}")}}
    {{#JSONparseSafe (getVar ../assign)}}
        {{! reencode the JSON string to cleanup whitespaces }}
        {{assignVar ../../assign (json this)}}
    {{/JSONparseSafe}}
{{/with}}

This is done such that the value attribute of the input element with name q can be pre-filled with the previous query by polling the stored value and doing some hackery to get just that value.

{{#JSONparse (getVar "temp")}}
    {{#each this.query}}
        {{#if @key "===" "q"}}
            <input
                type="search"
                placeholder="Search..."
                id="q"
                name="q"
                value="{{this}}"
            >
        {{/if}}
    {{/each}}
{{/JSONparse}}

cc @bigcommerce/storefront-team

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions