Using Advanced Layouts In SvelteKit
Published Feb 10, 2023
Table of Contents
- Previously
- Project Setup
- Sometimes You Want Routes With Different Layouts
- Using Group Layouts To Group Related Routes
- Breaking Out Of Layouts
Previously
This is part of a SvelteKit series and while each part is meant to be self-contained here are the previous parts in case you want to catch up:
- What is SvelteKit?
- SvelteKit Project Structure
- SvelteKit Routing
- SvelteKit API Endpoints And Loading Data For Pages
- Working With Forms In SvelteKit
Project Setup
If you want to follow along the easiest method is to open the starting project on StackBlitz but if you prefer the comfort of your editor I provided a repository on GitHub with the starting and final example.
Clone the project.
git clone https://github.com/joysofcode/advanced-layouts.git
After you clone the project you can install the dependencies and start the development server.
npm i && npm run dev
If you want to look at the solution switch the branch.
git checkout solution
Sometimes You Want Routes With Different Layouts
Letβs say I have a million dollar idea and itβs named Plume β a site for discovering and sharing inspiring quotes.
The investors are lined up but before I can push the yacht to sea I need to push the code into production but Iβve ran into a problem.
I shouldnβt be sharing trade secrets but hereβs the routes
structure.
routes
βββ admin
β βββ +layout.svelte
β βββ +page.server.ts
β βββ +page.svelte
βββ quotes
βββ id
β βββ [quoteId]
β βββ +page.server.ts
β βββ +page.svelte
βββ tags
β βββ [tag]
β β βββ +page.server.ts
β β βββ +page.svelte
β βββ +page.server.ts
β βββ +page.svelte
βββ +layout.server.ts
βββ +layout.svelte
βββ +page.svelte
Thatβs a sweet tree but it hides dark secrets.
If you navigate to /admin
youβre going to notice the first issue where the admin layout (/admin/+layout.svelte
) shares the root layout (/routes/+layout.svelte
) which makes me look like a clown in the eyes of the investors. π€‘
Yikes! But thatβs not everything.
Notice the /quotes
route? I want a layout that shows more quotes at the end of the page if I go to other child routes like /quotes/id/[quoteId]
but I might not want that layout for /quotes/tags
.
Sure, I could move the /tags
route outside the /quotes
route which would solve the problem but I donβt want to do that. Because every child route in /quotes
shares the same layout from /quotes/+layout.svelte
if you go to /quotes/tags
it shows other quotes.
This is where group layouts help.
Using Group Layouts To Group Related Routes
Group layouts let you group routes inside a directory wrapped in parenthesis but they donβt create a new route.
To fix the admin layout Iβm going to create an (app)
and (dashboard)
group. If you want the group to be the root (/
) of your app you can put the +page.svelte
file inside the group.
Iβm going to keep the global styles inside /routes/+layout.svelte
but move everything else which is going to leave us with a blank root layout.
<script lang="ts">
import '@picocss/pico'
import '../app.css'
</script>
<svelte:head>
<link rel="icon" href="https://fav.farm/πͺΆ" />
<title>Plume</title>
</svelte:head>
<slot />
Iβm going to move the navigation from /routes/+layout.svelte
and /routes/+page.svelte
including the /quotes
route inside the (app)
directory and then I only have to drag the /admin
route inside the (dashboard)
directory.
routes
βββ (app)
β βββ quotes
β βββ id
β β βββ ...
β βββ tags
β β βββ ...
β βββ +layout.svelte
β βββ +page.svelte
βββ (dashboard)
β βββ admin
β βββ +layout.svelte
β βββ +page.server.ts
β βββ +page.svelte
βββ +layout.svelte
Wonderful!
To fix the tags layout Iβm going to use a group layout to create separate groups for (quote)
and (tags)
under the /quotes
route and move the /quotes/id
route inside quotes/(quote)
and the /quotes/tags
route inside /quotes/(tags)
.
routes
βββ (app)
β βββ quotes
β βββ (quote)
β β βββ id
β β β βββ ...
β β βββ +layout.server.ts
β β βββ +layout.svelte
β β βββ +page.svelte
β βββ (tags)
β β βββ tags
β β β βββ ...
β β βββ +layout.svelte
β βββ +layout.svelte
β βββ +page.svelte
βββ (dashboard)
β βββ admin
β βββ +layout.svelte
β βββ +page.server.ts
β βββ +page.svelte
βββ +layout.svelte
Thatβs it!
I think what makes group layouts confusing is when you start nesting layouts because you can think of group layouts as buckets to put things into but if youβre not confident in using layouts yet this is going to be hard to wrap your head around.
If youβre not sure when to use a layout ask yourself if the child routes of a given route have some repeating content you want to show β also remember we previously learned that data returned from layout load
functions is available to child routes on the data
prop which is useful.
You donβt have to use group layouts, so put this away in your pocket in case you need it and focus on the fundamentals instead.
If you thought this was mind-bending in the next section Iβm going to show you that individual pages and layouts can also change layouts.
Breaking Out Of Layouts
Group layouts are nice if you want some pages and their children to have a different layout but you can also use a different layout for a specific page and layout.
Right now the /(app)/quotes/(quote)/id/[quoteId]/+page.svelte
route shares the app layout and quotes layout but if you didnβt want to use the quotes layout for showing more quotes you can use the app layout instead and rename +page.svelte
to +page@(app).svelte
.
routes
βββ (app)
β βββ quotes
β βββ (quote)
β β βββ id
β β β βββ [quoteId]
β β β βββ +page.server.ts
β β β βββ +page@(app).svelte
β β βββ +layout.server.ts
β β βββ +layout.svelte
β β βββ +page.svelte
β βββ (tags)
β β βββ tags
β β β βββ ...
β β βββ +layout.svelte
β βββ +layout.svelte
β βββ +page.svelte
βββ (dashboard)
β βββ admin
β βββ +layout.svelte
β βββ +page.server.ts
β βββ +page.svelte
βββ +layout.svelte
If you ever looked up how to reset a layout in SvelteKit you were probably confused because to do so you would need a blank root layout which only makes sense now after you learned about group layouts and breaking out of layouts.
If you want to reset a layout and use the root layout you can use an empty string +page@.svelte
or +layout@.svelte
to use the root layout.
The (app)/quotes/(tags)/+layout.svelte
route shares the app layout and itβs children are going to inherit the tags layout if you visit /quotes/tags
but if you wanted to change the parent app layout layout and use the root layout you can rename +layout.svelte
to +layout@.svelte
.
routes
βββ (app)
β βββ quotes
β βββ (quote)
β β βββ id
β β β βββ [quoteId]
β β β βββ +page.server.ts
β β β βββ +page@(app).svelte
β β βββ +layout.server.ts
β β βββ +layout.svelte
β β βββ +page.svelte
β βββ (tags)
β β βββ tags
β β β βββ ...
β β βββ +layout@.svelte
β βββ +layout.svelte
β βββ +page.svelte
βββ (dashboard)
β βββ admin
β βββ +layout.svelte
β βββ +page.server.ts
β βββ +page.svelte
βββ +layout.svelte
Now you know how to break out of layouts if you have to.
In the next part youβre going to learn about SvelteKit hooks before you learn how to deploy a SvelteKit project.