denoland / fresh

The next-gen web framework.
https://fresh.deno.dev
MIT License
12.54k stars 648 forks source link

Feat: trigger partial route change from JS #2229

Open sonickseven opened 10 months ago

sonickseven commented 10 months ago

I know about of partial and I applied the documentation fine, but in some cases I need change of page with logic(JS or TS) and I tried with window.location.href , document.location.href and location.href but in all cases the change of pages refresh all website.

How I can change with JS of page like for example navigate(/link/foo=bar); from reactjs or with Router.push() from nextjs

Also I tried with this code:

location.href = new URL(`/link/foo=bar`, location.origin).href;

But it doesn't work 😭

marvinhagemeister commented 10 months ago

Client side routing is done via Partials in Fresh, see https://fresh.deno.dev/docs/concepts/partials

sonickseven commented 10 months ago

But only works with tag A and I could't see how use that with JS, if you know that please show me one example 🙏

marvinhagemeister commented 10 months ago

Yeah it's currently limited to anchor tags and forms. There currently is no API to access it from JS.

Re-opening because a question turned into a feature request.

sonickseven commented 10 months ago

Yeah it's currently limited to anchor tags and forms. There currently is no API to access it from JS.

Re-opening because a question turned into a feature request.

When I was researching I saw this same problem in stackoverflow, reddit.

marvinhagemeister commented 10 months ago

Yeah it's currently limited to anchor tags and forms. There currently is no API to access it from JS. Re-opening because a question turned into a feature request.

When I was researching I saw this same problem in stackoverflow, reddit.

I'm afraid I don't track those places. I mostly monitor this repository here or our discord.

spy4x commented 2 months ago

+1

MrMarble commented 1 month ago

As a workaround, you can trigger it by having a hidden link and emitting the click event. Here's a component I use to have an infinite scroll using partials

// @ts-ignore override scrollTo as fresh forces scroll to the top when loading a parcial
globalThis._scrollTo = globalThis.scrollTo;
globalThis.scrollTo = () => {};

export default function Load() {
  const ref = useRef<HTMLAnchorElement>(null);
  const page = useSignal(1);

  useEffect(() => {
    if (!ref.current) return;

    // Detect when the component is inside the viewport
    const intersectionObserver = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        ref.current!.click(); // trigger click so fresh can load the partial
      }
    }, { threshold: 1 });

    const mutationObserver = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        if (
          mutation.type === "attributes" &&
          mutation.attributeName === "data-current" &&
          ref.current?.dataset.current
        ) {
          page.value += 1; // update the link once the partial has been loaded to prevent a loop
          delete ref.current!.dataset.current;
        }
      });
    });

    intersectionObserver.observe(ref.current);
    mutationObserver.observe(ref.current, { attributes: true });

    return () => {
      mutationObserver.disconnect();
      intersectionObserver.disconnect();
    };
  }, []);

  return (
    <a
      class="invisible"
      ref={ref}
      href={`/page/${page}`}
      f-partial={`/partials/grid/${page}`}
    >
      Load more
    </a>
  );
}