Relative paths for polyfill and element loading
matthewp opened this issue · comments
Currently the polyfill is added via an absolute URL (per the docs), as are any elements. If your site is hosted on a subpath from the domain like http://example.com/site
you need to add /site
as a prefix to any of these URLs. This can be cumbersome because often in development you are not using that prefix.
I usually try to make my URLs relative for this reason. It would be nice if Ocean could make these links relative to the current page. Here's an idea for maybe how that could happen (this is using a service worker API, but could work in Deno as well):
import 'https://cdn.spooky.click/ocean/1.0.0/shim.js?global';
import { Ocean } from 'https://cdn.spooky.click/ocean/1.0.0/mod.js';
let { elements, wrap } = new Ocean({ document });
elements.add('my-element', '/elements/my-element.js');
addEventListener('fetch', event => {
let html = wrap(event.request.url);
let iter = html`
<!doctype html>
<html lang="en">
<title>My app</title>
<my-element ocean-hydrate="idle"></my-element>
`;
});
In the above a relative link will be added for this script.
cc @lamplightdev if you have any opinions/ideas on this.
Could a urlRoot
be passed as a new entry in OceanOptions
instead, rather than having to manually wrap html
?
The issue there is you'd have to create a new instance of Ocean for every request and template compilation is cached in the ocean instances, so you'd lose all of that cached work.
I was thinking more along the lines of keeping the absolute urls, but just prefixing them with the option, e.g. /test
, that would work across requests, but I see now that you'd rather keep them relative. In your example how would you work out the different relative paths for say, http://example.com/site/foo
and http://example.com/site/foo/bar
?
Yeah, this issue is to keep them relative. If there's a prefix you need you can always just add that to your polyfillURL
and each element's path.
I'm now leaning towards relativeTo
as the name. I tried coming up with shorter names but I think it makes sense to be explicit. Ocean's intended to be a somewhat low-level library anyways that you build high-level ideas on top of.
let{ relativeTo } = new Ocean({ document, polyfillURL: '/scripts/dc-polyfill.js' });
async function homepage(request) {
let html = relativeTo(request.url);
html` ... `
}
I've started working on this a little bit.
PR ready in #36