ionic-team / capacitor

Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚡️
https://capacitorjs.com
MIT License
12.1k stars 1k forks source link

feat: Support loading from alternate path #3912

Open imhoffd opened 3 years ago

imhoffd commented 3 years ago

At runtime, we should support the use case of loading a file other than /index.html. For example: __app.html or en-US/index.html. This could also be a configuration option, but we should be able to override it at runtime to allow for use cases such as this: https://github.com/ionic-team/capacitor/discussions/3905

see https://github.com/ionic-team/capacitor/pull/3405 depends on https://github.com/ionic-team/capacitor/issues/3913

rraihansaputra commented 3 years ago

I'd like to share another usecase, currently I'm building a Capacitor app with Svelte and Routify, and for SSR purposes the default entrypoint is __app.html. Currently my workaround for building the Capacitor app both locally and in CI is to have a separate build step for the web app which copies dist/__app.html to dist/index.html prior to executing npx cap copy. If this can be configured, it would resolve the separate jobs needed to make this work.

sabahallah commented 2 years ago

Dear @imhoffd

Any luck when this could be resolved.

We now architecting an application that will use Angular built-in i18n for multi-lingual app. and with using Angular built-in i18n there would be a separate build for each language. We will use Capacitor as a hybrid mobile solution, but Capacitor copy the application from www directory, in my case there will be folder for each language. So how to handle this in Capacitor, and is it possible to change the URL in runtime as the user change the language.

meriturva commented 2 years ago

Any news here? we would like to use angular i18n and we have to decide how to proceed. Thanks!

UltraCakeBakery commented 2 years ago

There is currently no way to do native translations (that allow a user to only install for example the english version of your app in your app bundle. Capacitor has no easy configuration for this. You have to do this manually and it is a lot of work..).

You do however have access in your web app to https://developer.mozilla.org/en-US/docs/Web/API/Navigator/languages, which allows you to determine the devices preferred language.

meriturva commented 2 years ago

Thanks @UltraCakeBakery for your feedback.

My idea is to pack capacitor with all language folders produced by ng build and add an index.html file on the root folder. The root index file has just to check the device's preferred language and redirects to the correct folder.

What do you think?

UltraCakeBakery commented 2 years ago

Thanks @UltraCakeBakery for your feedback.

My idea is to pack capacitor with all language folders produced by ng build and add an index.html file on the root folder. The root index file has just to check the device's preferred language and redirects to the correct folder.

What do you think?

That'll work fine I think. It is all local so redirects won't hurt performance too much.

rdlabo commented 2 years ago

Thanks @UltraCakeBakery for your feedback.

My idea is to pack capacitor with all language folders produced by ng build and add an index.html file on the root folder. The root index file has just to check the device's preferred language and redirects to the correct folder.

What do you think?

This work well. I prepared this html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script type="text/javascript">
      // If true, you should set localStorage[storageKey] in your app.
      const saveLocale = true;
      const storageKey = 'locale';
      const defaultLocale = 'ja';
      const localeMap = {
        ja: ['ja', 'ja-JP'],
        'en-us': ['en', 'en-US'],
      };

      // Method
      const getBrowserLanguage = (navigator) => {
        if (!navigator) return null;
        if (navigator.languages && navigator.languages.length > 0) return navigator.languages[0];
        if (navigator.userLanguage) return navigator.userLanguage;
        return navigator.language;
      };
      const getToRoute = (locale) => {
        return Object.keys(localeMap).find((key) => {
          if (localeMap[key].map((l) => l.toLowerCase()).includes(locale)) return true;
        });
      };

      // Run redirect
      (() => {
        let locale = saveLocale === true ? localStorage.getItem(storageKey) : null;
        if (!locale) locale = getBrowserLanguage(window.navigator);
        if (saveLocale === true) localStorage.setItem(storageKey, locale);
        if (!locale) locale = defaultLocale;
        const route = getToRoute(locale.toLowerCase());
        console.log([new URL(window.location.href).origin, route, 'index.html'].join('/'));
        window.location.replace([new URL(window.location.href).origin, route, 'index.html'].join('/'));
      })();
    </script>
  </head>
</html>

Note: Capacitor require path/index.html. So subpath cannot be restored.

Erudition commented 1 year ago

Yes, it seems that setting server: url to ANYTHING (including the default, https://localhost/) prevents all localhost paths from working (Err Connection Refused). Would love to start somewhere else without losing the local server...

Erudition commented 1 year ago

Here's my current workaround, what do y'all think. Added a (p)npm script:

"capacitor:copy:after": "if [ $CAPACITOR_PLATFORM_NAME == 'web' ]; then echo leaving index in place for web. ; else echo replacing index with go-online... && mv android/app/src/main/assets/public/index.html android/app/src/main/assets/public/original.html && mv android/app/src/main/assets/public/go-online.html android/app/src/main/assets/public/index.html; fi"

Which moves the desired page to index.html for mobile platforms only. In my case, this lets me start at an external path (go-online is just a redirect) without losing the ability to navigate back to localhost.

selected-pixel-jameson commented 6 months ago

Would be great to see some movement on this. Ionic w/Angular standalone is pretty much dead in the water for localization options seeing as ngx-translate doesn't support standalone. With the advancement of AI it's only going to make more sense for solutions to incorporate localization since it is now becoming so affordable and easy to translate text. I only see the need for Ionic to support Angular's native localization to become more and more prevalent.

Even a solution that would let us give the end user an interface to toggle between, which would restart the entire application would be acceptable in my opinion, as long as it works with Angular's native translation packages, which are actually awesome.