Telegram-Mini-Apps / telegram-apps

Made from scratch TypeScript packages, examples and documentation you will surely need to start developing on Telegram Mini Apps.
https://docs.telegram-mini-apps.com/
MIT License
400 stars 79 forks source link

[Bug]: react-router-dom params with react-router-integration #276

Closed hiendaovinh closed 1 month ago

hiendaovinh commented 3 months ago

Telegram Application

Other

Describe the Bug

Hi, I was looking for a way to use react-router-dom route with params as mini app URL but it's impossible because of the HashNavigator implementation. Routes

[{
  path: "/foo/:param",
  Component: Comp
}]

There is no way to set https://127.0.0.1:5173/reactjs-template/#/foo/bar as the application URL.

To Reproduce

Steps to reproduce the behavior:

  1. pnpm dlx @tma.js/create-mini-app
  2. Language
    ❯◉ TypeScript
    ◯ JavaScript
    SDK
    ◉ tma.js
    ◯ Telegram SDK
    Framework
    ◉ React.js
    ◯ Solid.js
    ◯ Next.js
  3. pnpm i
  4. Setup SSL for the dev server with @vitejs/plugin-basic-ssl
  5. Use https://127.0.0.1:5173/reactjs-template/#/foo/bar as the application URL.

Expected Behavior

HashNavigator should persist the navigation state using the URL instead of the sessionStorage to make routes accessible.

heyqbnk commented 3 months ago

Do I get it right, that you would like to pass initial routing entries? I assume, the problem is in this line: https://github.com/Telegram-Mini-Apps/tma.js/blob/master/packages/react-router-integration/src/createNavigator.ts#L21

When we see, that page was not reloaded, we should not create a navigator with empty entries, but take a look at current hash and use it as the initial one.

hiendaovinh commented 3 months ago

Yeah, kind of. It depends on the expected type of router: BrowserRouter or HashRouter or MemoryRouter. From my point of view, it's the issue with the compatibility of react-router-dom stuff and HashNavigator. For instance, the Link component renders differently depending on the router used.

I tried to skip the HashNavigator and write a custom bridge between react-router-dom and tma.js/sdk like this:

const buttonBack = useBackButton();
  const location = useLocation();
  const navigate = useNavigate();
  useEffect(() => {
    function onClick() {
      navigate(-1);
    }

    buttonBack.on("click", onClick);
    return () => {
      buttonBack.off("click", onClick);
    };
  }, [buttonBack, navigate]);
  useEffect(() => {
    if (location.key === "default") {
      return;
    }

    if (!buttonBack.supports("show")) {
      return;
    }

    buttonBack.show();
  }, [location, buttonBack]);

No matter what kind of router we use (BrowserRouter / HashRouter), we could take advantage of react-router-dom to correctly render initial route (/foo/bar or /#/foo/bar) The only problem now is to keep telegram launch params when using <Link> to navigate.

hiendaovinh commented 3 months ago

Btw, it's easier to reproduce by visiting the mini app directly https://127.0.0.1:5173/#tgWebAppData=... and observe the URL changes.

BrowserRouter: App URL https://127.0.0.1:5173/foo/bar HashRouter: App URL https://127.0.0.1:5173/#/foo/bar

hiendaovinh commented 3 months ago

The only problem now is to keep telegram launch params when using to navigate.

Well this is more complicated than I thought.

# 1, navigate to this, render fine
https://127.0.0.1:5173/#/theme-params?tgWebAppData=user...

# 2, remove the launch params, render fine
https://127.0.0.1:5173/#/theme-params

# 3, change router path, Error: Unable to determine current environment and possible way to send event.
https://127.0.0.1:5173/#/launch-params

The session storage stays the same.

heyqbnk commented 3 months ago

The problem is at the moment, that HashNavigator is rather raw thing to be used in production. I could even say that integration for it was born in like 5 minutes. I remember creating the lowest level navigation class - Navigator, but it should probably also be reworked.

You are getting an error on the third step due to the reason, that you are launching the application outside of Telegram application, it is not related to react-router-dom or tma navigator.

This package part (navigation) will be reworked in the next 1-2 months. Currently, I don't really have much time for it. You could try researching the idea behind Navigator (the lowest level class) and HashNavigator (extending Navigator) and implement a navigator you need.

I am not closing this issue, as long as we have the exact problem. Will be back solving it after some time

hiendaovinh commented 3 months ago

Thanks for your pointer.

heyqbnk commented 2 months ago

Hey. I have just released a major update for tma.js ecosystem and worked a bit on the navigation utils. Could you try checking an updated version of the React template? Does it work fine for you now?