Search code examples
routesdenofreshjs

Deno Fresh framework page navigation/routing


  • Simply put, I'm creating a Fresh website with multiple pages, but something I cannot find is a way to navigate through the pages without a <a href='/about' /> component
  • For example, say I want to click a button and then navigate to the /about page, how would i do that?

https://fresh.deno.dev/docs/introduction


Solution

  • You would have to have the button in an island, or as a child of an island. That is the way to have JS on your page, which you will probably need if you want to use a button for navigation. Once in an island, you can use the onClick attribute and window.location.href="/about"

    I wouldn't do this though. The better approach is to use a <a>-tag if you are doing navigation and then style it the same as a button. That way your users don't lose out on any benefits of having a link for doing things that a link does (right click to copy url, ctrl/middle click to open in new tab, other web accessibility considerations, etc...).

    Using the delivered solution for what you are trying to do will be less work overall and make for a more usable solution.

    I often create a component that keys off of the href attribute to know if it should use a <button> or <a> tag. A simple version would be something like this:

    components/Button.tsx

    import { JSX } from "preact";
    
    export type Props<T extends HTMLButtonElement | HTMLAnchorElement> =
      & JSX.HTMLAttributes<T>;
    
    export function Button<T extends HTMLButtonElement | HTMLAnchorElement>(
      props: Props<T>,
    ) {
      const htmlClass = "ui-btn px-2 py-1 border-gray-500 border-1 rounded bg-white hover:bg-gray-200 focus:bg-gray-200 transition-colors font-normal";
    
      if (props.href) {
        return (
          <a
            {...props as Props<HTMLAnchorElement>}
            class={htmlClass}
          />
        );
      }
    
      return (
        <button
          {...props as Props<HTMLButtonElement>}
          class={htmlClass}
        />
      );
    }
    

    Then to use it:

    <Button>Normal Button</Button>
    <Button href="https://example.com">Link that looks like a Button</Button>