martpet
martpet8mo ago

How to use `f-partial` from Fresh?

Show me an example of using f-partial in a Deno Fresh project.
20 Replies
martpet
martpet8mo ago
Hey, bot
marvinh.
marvinh.8mo ago
Partials | Fresh docs
Partials allow areas of a page to be updated without causing the browser to reload the page. They enable optimized fine grained UI updates and can be used to do client-side navigation.
martpet
martpet8mo ago
Hi Marvin. Yes, I've been looking at the docs and the blog post, but I'm missing something.
marvinh.
marvinh.8mo ago
Happy to answer any remaining questions
martpet
martpet8mo ago
So I have: <div f-client-nav> <a href="somewhere">link</a> <Partial name="something"> </Partial> </div> Then I decided to add f-partial to the link and to move the <Partial name="somthing"> to it's own file , where app wrapper and layout is not used Now the question is what do I put in place of <Partial name="something"> in the code above
marvinh.
marvinh.8mo ago
The <Partial> component wraps the content that you want to be updated.
martpet
martpet8mo ago
I mean, there are two files: /routes/my
<div f-client-nav>
<a href="" f-partial="/partials/my-partial">
<Partial name="foo">
my content
</Partial>
</div>
<div f-client-nav>
<a href="" f-partial="/partials/my-partial">
<Partial name="foo">
my content
</Partial>
</div>
/routes/partials/my-partial:
<Partial name="foo">
my content
</Partial>
<Partial name="foo">
my content
</Partial>
Ok, I think I got it. my content should be duplicated - once in the parent file, and once in the partial file I thought somehow that on page load the initial content would be loaded from the partial file Thank you Marvin. If someone is curious, here is how I did it: /routes/items/[id]/_(components)/ItemPartial.tsx:
return (
<Partial name="item">
<h1>{props.item.title}</h1>
</Partial>
)
return (
<Partial name="item">
<h1>{props.item.title}</h1>
</Partial>
)
/routes/items/[id]/partial.tsx:
const item = await fetchItem();
return (
<ItemPartial item={item} />
)
const item = await fetchItem();
return (
<ItemPartial item={item} />
)
/routes/items/[id]/index.tsx:
const item = await fetchItem();
return (
<div f-client-nav>
<a href="/items/1" f-partial="/items/1/partial">Item 1</a>
<a href="/items/2" f-partial="/items/2/partial">Item 2</a>
<ItemPartial item={item} />
</div>
)
const item = await fetchItem();
return (
<div f-client-nav>
<a href="/items/1" f-partial="/items/1/partial">Item 1</a>
<a href="/items/2" f-partial="/items/2/partial">Item 2</a>
<ItemPartial item={item} />
</div>
)
marvinh.
marvinh.8mo ago
Yeah the partial file will only be requested upon user interaction
eduardobbrito
eduardobbrito8mo ago
hi, can you please help me? Something isn't clicking here I'm trying to display some static content as a partial, just to try things out and render a possibly expensive component on the server after the initial request I'm using deco.cx, but I believe the overall structure should be the same, as the component I'm trying to add a Partial to will be server redenred. /routes/partials/Modal.tsx
import { defineRoute, RouteConfig } from "$fresh/server.ts";
import { Partial } from "$fresh/runtime.ts";

export const config: RouteConfig = {
skipAppWrapper: true,
skipInheritedLayouts: true,
};

export default defineRoute(() => {
return (
<Partial name="modal-content" mode="append">
<p>expensive content</p>
</Partial>
);
});
import { defineRoute, RouteConfig } from "$fresh/server.ts";
import { Partial } from "$fresh/runtime.ts";

export const config: RouteConfig = {
skipAppWrapper: true,
skipInheritedLayouts: true,
};

export default defineRoute(() => {
return (
<Partial name="modal-content" mode="append">
<p>expensive content</p>
</Partial>
);
});
/sections/ProductGallery.tsx
<div f-client-nav>
<button f-partial={"/partials/Modal"}>MODAL</button>
{/* How do I import the Partial here since the Modal.tsx file doesn't return a JSX component? */}
</div>
<div f-client-nav>
<button f-partial={"/partials/Modal"}>MODAL</button>
{/* How do I import the Partial here since the Modal.tsx file doesn't return a JSX component? */}
</div>
What I think I'm missing is that I can't find a way to use the Partial declared on /partials/Modal.tsx as a component to be included in ProductGallery.tsx, so Fresh just logs me Partial "modal-content" not found. Skipping... seems like I've understood something wrong about the concept of partials.. My code was creating multiple partials with the same name, and thats not their intent. When using the partial a single time, it all works fine i wanted to have a modal rendered (component and all, with islands etc) on a server, but only when the user requests it. But I was calling it multiple times because I wanted to have a unique call for each item in a list for a product shelf!
marvinh.
marvinh.8mo ago
Yeah partial names are expected to be unique. Having multiple partials on the page with the same name doesn't work.
eduardobbrito
eduardobbrito8mo ago
yeah thanks! I'll look into how I can have several variations of content rendered for a modal content while having a single modal component
marvinh.
marvinh.8mo ago
Easiest solution would be to add another partial inside the modal one.
<Partial name="modal">
<div class="my-cool-modal">
<button class="close">...</button>
<Partial name="modal-content">
<p>here is cool content</p>
</Partial>
</div>
</Partial>
<Partial name="modal">
<div class="my-cool-modal">
<button class="close">...</button>
<Partial name="modal-content">
<p>here is cool content</p>
</Partial>
</div>
</Partial>
tavanogui
tavanogui7mo ago
can we do that with a different mode at nested Partial? <Partial name="modal"> <Partial name="modal-content" mode="append"> <p>here is cool content</p> </Partial> </Partial> I am trying to do that, but looks like that nested partials are ignored. My route at <a>-tag is entire page, should it work or just if I have a route that brings my nested partial?
marvinh.
marvinh.7mo ago
yeah just updating the inner partial should work
tavanogui
tavanogui7mo ago
any plans to make it automatic?