putyourlightson / craft-sprig

A reactive Twig component framework for Craft CMS.
https://putyourlightson.com/plugins/sprig
MIT License
129 stars 9 forks source link

Use custom URL for Sprig action requests #221

Closed martinhellwagner closed 2 years ago

martinhellwagner commented 2 years ago

Is your feature request related to a problem? Please describe.

We're currently facing the situation in which our site is running with one URL (e.g. https://www.domain.com), but the Sprig actions requests must be served with a different URL (e.g. https://content.domain.com/index.php/actions/...). Thus, I'm wondering if it's possible to use a custom URL for Sprig action requests.

Describe the solution you would like

A possible solution would be to set a custom URL for Sprig action requests in the sprig.php config file, which ultimately gets passed down to the _getSprigActionUrl function.

Describe alternatives you have considered

Currently, I'm replacing the "wrong" URL with the "right" URL directly in the _getSprigActionUrl function, which is by no means a clean solution.

bencroker commented 2 years ago

Can you explain the reasoning for using a different domain for action requests than the site domain, and how you're solving this for other action URLs?

martinhellwagner commented 2 years ago

Our client is only giving us the namespace https://www.domain.com/namespace, and they don't want requests to be served via https://www.domain.com/index.php/actions/.... Strangely, other action requests are not affected by this.

bencroker commented 2 years ago

I'm not following, both the URLs above are on the same sub-domain...

martinhellwagner commented 2 years ago

Yes, but we are not allowed to serve requests via https://www.domain.com/index.php/actions/..., but must serve them via https://content.domain.com/index.php/actions/..., which doesn't seem to work.

bencroker commented 2 years ago

We use Craft's UrlHelper::actionUrl() to generate the action URL at https://github.com/putyourlightson/craft-sprig-core/blob/0eea40527b119a70f3c69bd2f660209e0e7c4484/src/services/ComponentsService.php#L416

I don't see any reason to change this behaviour without a valid use-case, and it seems I still don't fully understand yours.

martinhellwagner commented 2 years ago

The problem is that UrlHelper::actionUrl() is using the Base URL (https://domain.com), whereas we need the action request to rely on Content Base URL (https://content.domain.com). I haven't found an option to change that.

bencroker commented 2 years ago

I understand what you're asking for, but without a common use-case there's little argument to be made for adding this to the plugin.

martinhellwagner commented 2 years ago

It's definitely not a common use case, but makes half our site broken in this case unfortunately. 😐

bencroker commented 2 years ago

So how are you dealing with this for other action URLs?

martinhellwagner commented 2 years ago

Other action links don't seem to have this problem.

What's more, the "hacky" fix with https://content.domain.com/index.php/actions/... doesn't seem to work when refresh is set as the trigger. In this case, it needs to be https://domain.com/index.php/actions/....

bencroker commented 2 years ago

Likely because you're coming up against CORS issues which prevent cross-domain AJAX requests.

martinhellwagner commented 2 years ago

@bencroker

I'll have a look at that.

A second issue that has come up after our go-live of https://www.karriere.at/blog is that a Sprig component (in this case the green header bar) is loaded with a noticeable delay every time the page is loaded. The s-trigger for this component is set to refresh, which I think is necessary because it's possible that the user is triggering an SSO login when clicking on the button "Anmelden", which leads the user away from the website and then back again – so a load or refresh trigger is needed in my understanding. Is there any way to make the Sprig component load instantly?

https://user-images.githubusercontent.com/19146752/166888972-37e1afc9-1e54-4b74-bc61-c8f38b760f5d.mp4

bencroker commented 2 years ago

There is, please reference the livestream at https://craftquest.io/livestreams/dynamic-content-on-statically-cached-pages in which I cover this topic in detail.

martinhellwagner commented 2 years ago

Thanks!

martinhellwagner commented 2 years ago

@bencroker

I've had a look at the talk. However, I'm wondering why in your example the component is rendered pretty fast, and in our example the rendering of the component takes a long while (which results in the component not being displayed for quite a long time). I've changed the trigger to load for my example.

bencroker commented 2 years ago

What does your component output initially? It looks like nothing, until the component is refreshed.

martinhellwagner commented 2 years ago

That is indeed true. This is how I'm referencing the component:

  {{ sprig('vite/_components-sprig/sso', {
    'appHandle': 'oauthclient',
  },{
    's-trigger': 'refresh',
  }) }}

And the component looks like this:

{% if appHandle is defined and sprig.isRequest %}
    ...
{% endif %}

This is of course only displayed when the first Sprig request is ready. So am I missing some "default" state that gets overwritten after the first request?

bencroker commented 2 years ago

Yes, as explained in the livestream, you'll want to follow this pattern.

{{ sprig('_components/my-component', {}, { 's-trigger': 'load' }) }}
{# _components/my-component.twig #}

{% if sprig.isRequest %}
    Dynamic content
{% else %}
    Default content
{% endif %}
martinhellwagner commented 2 years ago

Of course, an else condition – so obvious! I think that'll work great – thanks for the help! 🙂

hiasl commented 2 years ago

@martinhellwagner Did you get the issue solved, about the actionUrl starting with index.php ? We have the same problem...

martinhellwagner commented 2 years ago

@hiasl

No, unfortunately we ended up using the https://domain.com/index.php/actions/... action URL – which is not ideal to be honest.

hiasl commented 2 years ago

Hmm. It's interesting that you have pretty URLs and not GET params, because we get index.php?p=actions/... from Sprig. Did you try setting the dirName of your choice as part of the site's Site URL? Because other pretty action URLs we get, e.g. image transformations are created as <Site URL with dir>/actions/blablabla...

bencroker commented 2 years ago

@hiasl The image transform URL explicitly sets the $showScriptName parameter to false, so that the index.php is excluded. https://github.com/craftcms/cms/blob/b1ee3e69903e9c2ad1dce1b64813dc865d058d59/src/imagetransforms/ImageTransformer.php#L163

hiasl commented 2 years ago

@bencroker yeah, you're right, this is the difference. thanks for finding this out!

@martinhellwagner this might be interesting for you: https://github.com/putyourlightson/craft-sprig/issues/257#issuecomment-1239469060