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

Feature: Layouts #403

Closed
einSelbst opened this issue Jul 4, 2022 · 16 comments
Closed

Feature: Layouts #403

einSelbst opened this issue Jul 4, 2022 · 16 comments
Milestone

Comments

@einSelbst
Copy link

I know this might not be the most important feature at an early stage, but something I would love to see.

It might also be something which could be considered when working on #380

Nextjs support for layouts wasn't really great and now it's the main thing they are working on, https://nextjs.org/blog/layouts-rfc. Probably something good for inspiration.

Someone who experimented with different ways to define layouts (in nextjs), which might also be worth looking at: https://adamwathan.me/2019/10/17/persistent-layout-patterns-in-nextjs/

@ajf-sa
Copy link
Contributor

ajf-sa commented Jul 4, 2022

We can implement layout like this for now #371
✍️

@antoninbeaufort
Copy link
Contributor

I was wondering, is there any technical reason not to implement a layout/routing system a la Remix? https://remix.run/docs/en/v1/guides/routing
Or is it a non-technical decision?
For me the ideal framework is based on Deno, without build (like Fresh) but also has this layout system (from Remix) which allows to load only a part of the page when changing URL.
If you like this idea, I would love to work on it!

@lucacasonato
Copy link
Member

which allows to load only a part of the page when changing URL.

Fresh would never have this, because it uses full page transitions, not client side routing.

@lucacasonato
Copy link
Member

But layouts in general might be useful. I'd want us to figure out the exact semantics before anyone starts implementing though.

@vorcigernix
Copy link
Contributor

Oh. I misunderstood the impact of what @lucacasonato is saying here. Ouch. It is logical if we think about the nature of the framework, but at the same time it disqualifies the framework from some use cases (or I can't figure out how to do it). What it means is that the page (as it is static) always completely rerenders. So if you have a template with navigation, page1 and page2 and navigate from page1 to page2 it completely reloads the page (including the template part). Also, state of page1 is probably lost.
I am having this exact problem rn, so I will update here. I am thinking of moving the template to the islands and making the subpages a child components of this component. This will result in all pages having some javascript, but I guess there is no way around it.

@iamsahilsonawane
Copy link
Contributor

Oh. I misunderstood the impact of what @lucacasonato is saying here. Ouch. It is logical if we think about the nature of the framework, but at the same time it disqualifies the framework from some use cases (or I can't figure out how to do it). What it means is that the page (as it is static) always completely rerenders. So if you have a template with navigation, page1 and page2 and navigate from page1 to page2 it completely reloads the page (including the template part). Also, state of page1 is probably lost. I am having this exact problem rn, so I will update here. I am thinking of moving the template to the islands and making the subpages a child components of this component. This will result in all pages having some javascript, but I guess there is no way around it.

I am with you on this. @lucacasonato maybe we can have a micro framework for islands which will do this internally letting us handle nested page routes?

@tzakharko
Copy link

I would like to add my voice to @vorcigernix and @iamsahilsonawane I really like Fresh's distinction between routes and islands, but doing a full reset at page transitions does seem limiting for many applications. Most of all, I think it is surprising to the user if all the interactivity is reset when they refresh the page or click a link (one can already see it on the fresh website with the resetting counter). I would be great if there was a way to preserve state across reloads where it matters. And sure, there are ways to work around it, but I think that Fresh would be appealing to a wider user base if it offered such capabilities.

@drawveloper
Copy link

drawveloper commented Jul 12, 2022

Hi everyone! Great discussion. I would like to add my opinion. While there are plenty of alternatives of frameworks that do client side navigation, I understand that the purpose of fresh is precisely to lessen the complexity of the JS shipped to the browser and rely on good old server-side navigation semantics. Consider that this allows for a much simpler mental model for developers, while also reducing the shipped JS footprint and overall surface area for bugs. The best code is no code, right? My point is that you are interpreting server-side navigation as a limitation, where in reality it's fresh's main feature (in my viewpoint). For state management, you can rely on cookies and server-side state using something like Redis. Hopefully, deno deploy will also give us some high-level state-storage building blocks soon. Let's just not throw out the baby with the bathwater :)

@egmaleta
Copy link

Hello folks, you might want to check this

@marvinhagemeister marvinhagemeister added this to the Fresh 1.4 milestone Jul 12, 2023
@lveillard
Copy link

Hello folks, you might want to check this

Looks great!

  • Does this work similar to nextjs layouts? The layout keeps stable when changing the url?

  • How does it work to use island components inside the layouts? For instance, if there is a signout/sign in button that depends on the user being logged or not (which needs to dynamically change if that state changes), or just imagine a little counter with a button (because... why not?)

@mfulton26
Copy link

I'm looking at building a site where every route shows different content overlaying Google Maps tiles. From what I can tell, this can't currently be done with Fresh unless I set up client side routing and use islands for every "route" because otherwise each page navigation will have to re-render the map tiles (not ideal).

I think server-side layouts would be a great addition to Fresh on its own. I would, however, like to see via a plugin or an opt-in feature a way to ship a little more JavaScript to the browser to load pages from the server that share layouts and reconcile the difference and update the current document rather than rendering a new document from scratch.

@mcgear
Copy link
Contributor

mcgear commented Jul 22, 2023

I would think we want something simple and easy, that functions like other aspects of the Fresh framework. Something similar to:
https://fresh.deno.dev/docs/concepts/app-wrapper

While this may not be the fully featured Layouts type solution your looking for, it opens the possiblities to how routes can share Layouts (simplifying the task of applying layouts).

Maybe adding an _layout.tsx file in a sub folder (at any level) under routes would apply that template in a similar way as the app wrapper:

// routes/dashboard/_layout.tsx

import { LayoutProps } from "$fresh/server.ts";

export default function Layout({ Component, state }: LayoutProps ) {
  //do something with state here
  return (
    <div class="layout">
      <Component />
    </div>
  );
}

This is definitely something i would like to do, as now, to achieve layout i have to apply a ... wrapper around all the dashboard pages.

In fact i have just completed an initial set of dev in this PR: #1506

This supports a use case i think is pretty common in these types of frameworks in order to share layout, meta tags, and context amongst sub sections of a site.

@marvinhagemeister
Copy link
Collaborator

@mcgear +1 on going the _layout.tsx way. Will take a look at the PR on Monday.

@lveillard Layouts will work similar to nextjs, but I think what you're asking for is client side routing. To me that's separate from the ability to inherit layouts during rendering. Islands would work the exact same way in layouts as they do with routes today. From the renderer's perspective it's not relevant if it's rendering a route or a layout that then renders a route. It just sees a bunch of components that could contain islands.

@mcgear
Copy link
Contributor

mcgear commented Jul 22, 2023

I went for something lightweight that focuses on some simple changes to the manifest and then simply updates the renderer to account for n* layers of _layout.tsx files. Mimics aspects of the _middleware and _app concepts to derive a solution that should map fairly well to how the rest of the framework is operating.

@marvinhagemeister
Copy link
Collaborator

Just merged #1506 which adds support for hierarchical layouts similar to nextjs or remix. Note that this PR only affects authoring of layouts, not client side routing which other comments here talk about.

@marvinhagemeister
Copy link
Collaborator

Layouts have now landed in Fresh and will be part of the upcoming 1.4 release. Made a new issue for discussion client side navigation here #1609

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests