Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relative base such as ./ #606

Open
brillout opened this issue Jan 23, 2023 · 14 comments
Open

Relative base such as ./ #606

brillout opened this issue Jan 23, 2023 · 14 comments
Labels
enhancement ✨ New feature or request

Comments

@brillout
Copy link
Member

brillout commented Jan 23, 2023

Description

Vite supports setting base to ./ for "embedded deployments", see vite.config.js#base. Can Vike support such relative base paths?

@brillout brillout added the enhancement ✨ New feature or request label Jan 23, 2023
@brillout

This comment was marked as outdated.

@brillout brillout closed this as not planned Won't fix, can't repro, duplicate, stale May 31, 2023
@brillout
Copy link
Member Author

brillout commented Oct 31, 2023

Problem

When pre-rendering, because the HTML is set in stone, static assets need to be referenced with relative paths (e.g. ../../assets/* instead of /assets/*). Same for links.

<!-- URL (logical): / -->
<!-- URL (real, example 1): /some-base/ -->
<!-- URL (real, example 2): /some/nested/base/ -->
<img src="./assets/logo.aeuh81a.svg" />
<a href="./about-us" />
<!-- URL (logical): /product/edit/42 -->
<!-- URL (real, example 1): /some-base/product/edit/42 -->
<!-- URL (real, example 2): /some/nested/base/product/edit/42 -->
<img src="../../assets/logo.aeuh81a.svg" />
<a href="../../about-us" />

Solution

import { makeUrlRelative } from 'vike'
import { usePageContext } from 'vike-{react,vue,solid}'
import logoUrl from './logo.svg'

function SomeComponent() {
  const pageContext = usePageContext()
  return <>
    <a href={makeUrlRelative('/product/42', pageContext)} />
    <img src={makeUrlRelative(logoUrl, pageContext)} />
  </>
}

Contribute

  • Upvote this issue: react to first post with 👍 (increasing the priority of this feature request).
  • Research whether other SSR frameworks support this.
  • Sponsor (substantially increasing the priority of this feature request).
  • Research whether crawlers support relative URLs, and whether they support <base>.

Remarks

  • Do crawlers support relative URLs?
  • Could <base> be a simpler solution?
    • But do crawlers support <base>? Open Graph doesn't support <base> and, in general, I can imagine that many(/most?) crawlers don't support <base>. A non-crawlable website is a no-go.
  • While using Vite's viteDevServer.transformIndexHtml(url, html) could be an option for pre-rendering, it only applies to HTML which is only half the story. (And Vite's HTML transformer cannot be applied for SSR in production.)
  • Imports of static assets need to be handled
    // The value of logoUrl is static & absolute, not good
    import logoUrl from './logo.svg'
  • It isn't an option to let the user always define relative relatives because it's very brittle: for example a component function LinkProducts() { return <a href="./products">List of Products</a> } breaks for the route /product/edit/42 (the correct path for that route is ../../products/).
  • Vike needs to know whether pageContext.urlOriginal contains a base and what it is.
    • On the server-side.
      • E.g. how can Vike know that renderPage({ urlOriginal: '/some-base/product' }) has a base /some-base/?
      • If the user uses a reverse proxy, then we don't need this as urlOriginal doesn't contain the base. (The base is only contained in the URL on the browser.)
        • Same for pre-rendering, this isn't needed.
      • If the user doesn't use a reverse proxy: renderPage({ urlOriginal: '/some-base/product', urlBase: '/some-base/' }).
    • On the client-side.
      • Vike cannot tell whether window.location.href contains a base.
      • I guess passing something like pageContext.urlOriginalWithoutBase from the server to the client does the trick.
  • When using SSR instead of pre-rendering, URLs don't need to be relative: they can be absolute and dynamically resolved instead.
    • This should be an option (even better the default whenever possible), which is important if crawlers don't always support relative URLs.
    • We should therefore rename makeUrlRelative() to applyBase().

@brillout

This comment was marked as outdated.

@brillout brillout closed this as not planned Won't fix, can't repro, duplicate, stale Nov 15, 2023
@lsegal
Copy link

lsegal commented Nov 20, 2023

Fun timing on this one, I just came across this limitation when trying to use Vike for a project. The lack of support here is a little bit of a blocker for my use case in which the app is served by Vite/Vike via SSG and exposed indirectly via a proxy attached to arbitrary base paths-- in particular, there is no one specific fixed path, and it is chosen entirely by the proxy, not the application sitting behind it. Think about it like this (it's not exactly this, but this use case would fail in the same way): I'm generating a self contained application that is vended out to third parties all over the Internet and will be hosted in a white label fashion on various external properties at various locations. The static generation is an important piece to this limitation, as this works fine via SSR (since we can hijack routing) but breaks when generating static files. Unfortunately, static pre-render generation was the entire purpose for using Vike in the first place.

A lot is being mentioned about "assets", and I'm not entirely sure if Vike classifies its own chunks/compiled assets as "assets" in the same sense, but in my case, the big issue that breaks are the <script> tags, which I am assuming(?) is managed by Vike(?).

image

It isn't clear whether this is possible

I'm a little confused about the "possible" statement, as surely it is explicitly "possible" to generate relative links between documents (certainly this is a well known and very-solved problem). Is there some Vite API getting in the way? If so, that seems odd, since Vite itself supports a relative base.

Are there any workarounds for this use case, or is Vike not going to work for this use case?

@brillout
Copy link
Member Author

I agree your use case makes sense. What isn't clear is whether it's feasible to achieve that without ending up with a frankenstein (e.g. relative links are fundamentally broken in multi-page React/Vue/... apps).

Is there any React/Vue/... SSR framework out there that supports relative base paths? I honestly doubt it, but I'm happy to be shown wrong.

Also sponsoring welcome (you'll get a bump in priority).

@jwahdatehagh
Copy link

It isn't an option to let the user always define relative relatives because it's very brittle: for example a component function LinkProducts() { return List of Products } breaks for the route /product/edit/42 (the correct path for that route is ../../products/).

Couldn't this be handled within a <RouterLink> component (or similar)?

The logic doesn't seem too wild to me: Prepend links with ./ and then a ../ for every nesting level before linking to assets or pages?

I could have sworn this existed in Nuxt once but it's broken there rn.

Relevant for static deployments to e.g. IPFS, since you don't know the path the deployment ends up in before building.

@brillout

This comment was marked as outdated.

@brillout
Copy link
Member Author

Another use case: #1223 (comment).

@brillout
Copy link
Member Author

Re-opening as there seem to be a solution for this.

@brillout brillout reopened this Jan 17, 2024
@brillout brillout changed the title Relative base path (e.g. ./admin/ instead of /admin/) Relative base such as ./ Jan 17, 2024
@CookedApps
Copy link

We are currently experiencing challenges regarding this issue. Our use case involves deploying our React application in two distinct environments, each with unique requirements:

  1. As a pre-rendered MPA on Cloudflare Pages. This deployment has a fixed base path, needs to be crawlable and optimized for search engines.

  2. Embedded within an iframe on our partner's website. In this scenario, the application doesn't need to be crawlable and could potentially operate as an SPA without the pre-rendering, although pre-rendering is preferred for improved loading times. A significant challenge here is the base path, as the app is hosted at a randomly generated path after each deployment which is beyond our control, requiring relative base path support on our end.

We really need support for a relative base path in Vike, or a feasible workaround (possibly without pre-rendering?) for the second mentioned environment. So this issue is a critical deal-breaker for us.

If we can ensure that the necessary support will be available before June, I am willing to provide financial support for the project as well, as Vike is an otherwise perfect fit for our needs. 🙌

@brillout
Copy link
Member Author

@CookedApps

So this issue is a critical deal-breaker for us.

I see.

If we can ensure that the necessary support will be available before June, I am willing to provide financial support for the project as well

While I beileve the aforementioned solution will work, there are quite a lot of higher priority things in the pipeline, especially given that I foresee the implementation to be far from trivial. So I'm not sure how much sponsoring would help, but it depends on how much you'd be willing to sponsor. Feel free to PM us.

Also, what would help is doing some research wehther other frameworks support that. It would help us a lot to see a real world solution to this.

@CookedApps
Copy link

I see why this is a problem for MPAs and SSR environments. But I wonder if it would be possible to make relative base paths work in an SPA. For our use case we only need relative base path support for one customer specific deployment where we don't need to support pre-rendering, SSR nor being crawlable in the first place.

Therefore, switching the entire Vike app to SPA "mode" + client side routing should technically allow us to add a relative base path, right?

@brillout
Copy link
Member Author

brillout commented Feb 8, 2024

@CookedApps I'm reluctant to work on a solution that would work for only a small minority of users, even if it means less work.

@CookedApps
Copy link

@brillout I understand and respect your stance on not focusing on features for a minority of users. I'm not expecting you to invest time in our specific issue, but I would appreciate any guidance or suggestions for possible workarounds.

I'm also open to contributing to Vike directly and enrich the framework by adding such functionality. A bit of initial direction from the maintainers would be really helpful, as I'm currently finding it challenging to get involved, despite my enthusiasm for the project.

Thanks for considering this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement ✨ New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants