Creating a Component Prop0:27
like a nav and a footer, but for the content that does change, usually you would render that in a slot. So again, we'll take a look at layouts later on in SvelteKit, but for now let's just take a look at some examples within Vanilla Svelte. So I have a blank Svelte app here. Let's go ahead and make a new component. Let's name it AnotherSvelte. And for now let's accept a prop like we've been doing. So let's say export, let's name it name. And in our markup, let's just say, hello, name.
So let's say export, let's name it name. And in our markup, let's just say, hello, name. And in our parent component, let's just put it right here. Let's say another, let's pass in that prop, name equals Andre. And that's how you would pass props around in normal Svelte. Let's make sure to import another. And that should work. Now, like I said, slots are almost the same, but they allow you to pass markup around. So say, for example, instead of a string, I wanted to pass some HTML in here. Now you can pass it in as a string, but that wouldn't be the best experience.
Using Default Slots1:26
So say, for example, instead of a string, I wanted to pass some HTML in here. Now you can pass it in as a string, but that wouldn't be the best experience. So what you can do is pass it in as a slot instead. So instead of passing it in like this, we can pass it in between the tags of the component. So let's say, let's make it an h1 actually, let's pass in my name here. And then now we can close the component tag. And the h1 does have a style on it. If you scroll down here, you'll see we have some styles for the h1. And since it's defined within this component, it will still make use of those styles. So now to render this within the child component, let's just save this, let's go to our child.
And since it's defined within this component, it will still make use of those styles. So now to render this within the child component, let's just save this, let's go to our child. Instead of rendering the prop, we can render the slot being passed in. So we can say slot for the default slot. And that should be rendered as an h1 in the child, there it is. You can also provide a default value or a fallback just like you can with props. So with props, if you didn't define a prop, you can just define a default here. And with slots, you can do something similar. So let's just say div default goes here. And again, you can put any markup you like in here.
Adding Slot Fallbacks2:33
So let's just say div default goes here. And again, you can put any markup you like in here. Let's close out that slot. Let's go back to the parent here. Let's provide another component here, or another instance of this component, but with no slot passed in. And that should render the default slot or default back. And there it is. Now what if you wanted to pass in multiple slots? Right now we can only accept one.
Creating Named Slots2:58
Now what if you wanted to pass in multiple slots? Right now we can only accept one. But if we use name slots, we can use more than one. So let me just remove this one, what we can do is name our slots here. So let's name this one firstName. Let's make another slot here. This one, I'll make an h3. Let's name this one lastName. And let me put in my last name here. Go ahead and save that.
And let me put in my last name here. Go ahead and save that. And now we can define these slots within the other component here. So we can give these slots names, say slotName equals firstName. And again, we can provide a default if we like, let's just say defaultFirstName goes here. And we can do the same for lastName as well. Okay, change this to lastName. And our two slots should be rendered correctly in the browser. And it does.
Refactoring ContactCard Slots3:45
And our two slots should be rendered correctly in the browser. And it does. So again, we pass this one as an H1, this one as an H2. And if you check out DevTools, you can see my first name is within an H1, and my last name is within an H3. Thought I used an H2, no it's an H3, okay. Let's take a look at one more practical example that sort of brings everything together. So I have this ContactCard component here. It's meant to show contact information for a certain person. So right now we're making use of props.
It's meant to show contact information for a certain person. So right now we're making use of props. And you can see I have some defaults in place for all of these fields. Here is the markup for the contact card. Again, we're just outputting the props here. And I have some styles, so it looks decent. Let's go ahead and make use of this in our parent component. So let's just comment this out for now. Let's say contact card. And let's make sure to import that.
Let's say contact card. And let's make sure to import that. Okay. And let me just duplicate it so we have two instances. Okay. Let's see how that renders. So you can see them stacked here. Let me just put them in a flex container so they are beside each other. So let's just say .flex. And let's make a style here for a flex container.
Or maybe you want to add icons to this information down here. Now when we're using props, we can't do this because all of the markup is defined within the component. So it has to be the same for each instance. So all of this information within this component, you can't really change. Well, you can change it, but it will be the same for each instance. So for example, if I were to add a class here, let's say name, and we add a style down here, say contact-card-name, let's change the color to red. It's going to be the same for each instance. So it should be red for both of my contacts.
And let me just duplicate this, and we'll comment one out so you can see the difference between the two. But now we're going to replace our props with named slots. So for this one, let's say slot name equals name. And let's add a fallback here as well. And let's just say <h2>, no name. And we can do the same for the others as well. So let's remove this. Let's add one for title. Let's make the default a <div> instead.
Let's add one for title. Let's make the default a div instead. And we'll say no title. And pretty much the same for these three. So I'll just paste those in. Okay, so we replaced our props with named slots. Now in our parent component, instead of passing in props, we can pass in slots. So again, I'll just comment these out. So you can compare. Let's say contact card.
So you can compare. Let's say ContactCard. And now we're passing in named slots. So let's pass in an h2 for our name. Let's say slot equals name. And again, you can pass anything you like in here. So we can say class equals custom-name. Let's put in my name here. Let's do the same for our title here. But let's make it a div instead.
Let's do the same for our title here. But let's make it a div instead. slot is title. Let's give it a class of custom-title. Let's make sure to change the content. And let me just add these custom classes within our style here. So since we're defining it in this component, we need to define the style within this style block. Or you can make it global. It's up to you.
Or you can make it global. It's up to you. I'll just put it within here. Custom name. Let's make it red. And custom title. Sorry, it should be class. Let's make it green. So I'm just going to zero out the margin here as well. Let's do the same for our title here.
So I'm just going to zero out the margin here as well. Let's do the same for our title here. And let's see how this looks in the browser. Okay, so you can see those classes are being used. But if we were to add another instance of this component, you'll see that it's just the default color. So we can customize each component how we like because we're passing in the markup for each of the contact fields. So we can add any classes to them. We can even add different markup if you want to.
So we can add any classes to them. We can even add different markup if you want to. And I'll show you that in a second. And we'll add icons to the address fields. So let me just duplicate this. Let's change this to Elon. Again, we have complete control over the classes and the markup. So we can either add another class here, or we can just remove it completely. So let's just add two, which doesn't exist. We can add custom styles to that, or just leave it to default, which I'll do here.
Customizing Slot Markup9:28
So it's not rendering the fallback content for the slot. Okay, so I added slots for address, phone, and email for both instances here, and that should be rendered in our cards, and they are. But again, since we're using slots now, we have total control over the markup. So if you wanted to, we can even add, say, an icon next to these fields here. So let's do that for this instance here. So that would be this here. Let's go ahead and wrap this in a span, and this one as well. For now at least, and this is where the icon will go. See if that works, and it does.
height and the width, so let's just add a class here called CustomSVG. Let's add a style for that in our styles, CustomSVG should be a class, and let's just give it a height and a width. Let's just say 16 pixels, and same for width. Okay, let's see how that looks, back to our app, and there's the icon. And you can do the same for the other fields as well. So yeah, definitely make use of slots when you need to pass around markup between your components as they can add some level of customization as opposed to just using regular props.
