DEV Community

Parables
Parables

Posted on

What's new in `svelte-kit, 1.0.0-next.445`: (group) layout

SvelteKit is moving at the speed of sound to reach v1.0.0 and hence the team is juggling between pressure from the community to publish features proposed in the RFC while early adopters rant about how the team is not giving them enough time to soak in the new changes.

However, these changes are aimed at making the framework more expressive and simple and that's what we all want and love about Svelte

[Tip] Please follow the Discussions and read the CHANGELOG.md to stay updated on the breaking changes

What's Changed

  • (group) layout replaces named-layout #6124
    • #6124 in particular makes it very easy to avoid hacking named-layouts to break out of the inherited layout that was released in svelte-kit, 1.0.0-next.306 #4388. See CHANGELOG.md

The Problem with Named Layouts

Named Layout allowed you to specify exactly which layout your +page.svelte and +layout.svelte files should inherit by appending @name where @name is the part of the layout file name between the +layout- and .svelte extension.

Example: a +page.svelte or +layout.svelte file that wishes to inherit from a layout with the name +layout-settings, would have to be renamed as +page@settings.svelte or +layout@settings.svelte respectively

Using folder structure:

src/routes/
├ courses/
│ ├ +page.svelte
│ └ +page.ts
├ lecturers/
│ ├ +page.svelte
│ └ +page.ts
├ schedules/
│ ├ +page.svelte
│ └ +page.ts
├ settings/
│ ├ +page@settings.svelte
│ └ +page.ts
├ login/
│ ├ +page@auth.svelte
│ └ +page.ts
├ register/
│ ├ +page@auth.svelte
│ └ +page.ts
├ [deeplink=action]/
│ ├ +page.svelte
│ ├ +page.ts
│ └ +layout@root.svelte
├ +layout.svelte
├ +layout-auth.svelte
├ +layout-settings@default.svelte
└ +layout-root.svelte
Enter fullscreen mode Exit fullscreen mode

Will give us the following routes:

/
/courses
/lecturers
/schedules
/settings
/login
/register
/reset-password?email=parables95@gmail.com - deeplink
/verify-email?email=parables95@gmail.com - deeplink
/success?onboarding=done$redirectTo=home - deeplink
Enter fullscreen mode Exit fullscreen mode

Looking at the folder structure above:

  • the /courses, /lecturers and /schedules routes will inherit from the layout from src/routes/+layout.svelte
  • the /settings route will inherit from both the default parent layout src/routes/+layout.svelte and the src/routes/+layout-settings.svelte layout
  • likewise, the /login and /register routes will break out from the default parent layout src/routes/+layout.svelte and will rather inherit from the src/routes/+layout-auth.svelte layout
  • the deeplink routes will inherit from the immediate layout file src/routes/[deeplink=action]/+layout@root.svelte which in turn will also inherit from the named layout src/routes/layout-root.svelte since it explicitly specifies the @root in the layout name

This layout hacking method will it makes it easy to infer the routes using the folder structure makes it a bit harder to understand where routes belongs to.

For example I would want to group /courses, /lecturers and /schedules under dashboard but if I create a new directory src/routes/dashboard and the routes into the dashboard directory, my routes becomes /dashboard/courses, /dashboard/lecturers and /dashboard/schedules and that's is not what I want. I want to keep them on the index level and not nest them in the /dashboard level.

(group) layouts to the rescue

To address the problems posed by named-layouts, (group) layouts allows you to group your routes in a a special directory which is named in parenthesis (dashboard) to indicate that this directory is only meant for group layouts and hence it doesn't appear in the route's URL

Our new folder structure now becomes

src/routes/
├ (dashboard)/
│ ├ courses/
│ │ ├ +page.svelte
│ │ └ +page.ts
│ ├ lecturers/
│ │ ├ +page.svelte
│ │ └ +page.ts
│ ├ schedules/
│ │ ├ +page.svelte
│ │ └ +page.ts
│ ├ settings/
│ │ ├ +page.svelte
│ │ ├ +page.ts
│ │ └ +layout.svelte
│ ├ +page.svelte
│ ├ +page.ts
│ └ +layout.svelte
├ (auth)
│ ├ login/
│ │ ├ +page.svelte
│ │ └ +page.ts
│ ├ register/
│ │ ├ +page.svelte
│ │ └ +page.ts
│ └ +layout.svelte
├ (deeplink)
│ ├ [deeplink=action]/
│ │ ├ +page.svelte
│ │ └ +page.ts
└ +layout.svelte
Enter fullscreen mode Exit fullscreen mode

Our directory now looks cleaner, and it is more easy to reason out where the layout belongs. Knowing that any folder in parenthesis () wont, appear in the URL, one can easily read out the the route structure, by ignoring any (group) named folder in the hierarchy.

  • the /courses, /lecturers, /schedules and the /settings routes will all inherit from the layout from src/routes/(dashboard)/+layout.svelte as well as the src/routes/+layout.svelte

  • /login and /register will also inherit from src/routes/(auth)/+layout.svelte as well as the src/routes/+layout.svelte

  • While src/routes/(dashboard)/+page.svelte will be the index/homepage.

  • Remember, (dashboard) is ignored in the route hierarchy making src/routes/(dashboard)/+page.svelte at the same level as src/routes so please keep that in mind before you throw another +page.svelte at the same level or else SvelteKit will crash and throw back at you a nice error message

Error:  and (dashbaord) occupy the same route
Enter fullscreen mode Exit fullscreen mode
  • Pages and layouts inside groups — as in any other directory — will inherit layouts above them, unless they break out of the layout hierarchy.

  • A page can break out of a layout by specifying the name of the folder that contains the layout file you want to inherit.

  • For example to beak the /settings route from inheriting from the src/routes/(dashboard)/+layout.svelte to rather inherit a parent layout above it like the root layout in src/routes/+layout.svelte, you can rename src/routes/(dashboard)/settings/+page.svelte to src/routes/(dashboard)/settings/+page@.svelte where @ represents the root layout in the hierarchy.

  • Also, if there are parent layouts in the hierarchy above that you want a page to break out of its current inheritance and inherit from parent layout, specify @(parent-group) or @parent-folder

  • To break out of the layout uses a similar convention as the page. Simply use @ followed by the name of a folder above in the hierarchy where the layout you want to inherit is like @(parent-group) or @parent-folder.

  • +layout@.svelte  component would reset the hierarchy for all its child routes.

Migrate your SvelteKit app to use (group) layouts

  • Delete the node_modules folder and the .sveltekit and the package-lock.json or the -lock file for any package manager you are using
rm -rf node_modules .sveltekit
rm package-lock.json # change it as per your package manager `pnpm` or `yarn`
Enter fullscreen mode Exit fullscreen mode
  • And reinstall the packages again using your preferred package manager
npm install
Enter fullscreen mode Exit fullscreen mode

This is necessary in order to ensure that you have the latest versions of the dependencies.

  • npm-check-updates ncu may not be helpful here so play it safe and reinstall all your dependencies

That is the cost you've to pay for rolling on the bleeding-edge

Conclusion

SvelteKit is amazing and Rich-Harris and the team are making great improvements to make it more awesome.
We really appreciate them for everything they are doing to make out lives easier and simple as developers.

Seen a typo, noticed something wrong in the article, still confused, share your thoughts in the comment section below or find me on Svelte's Discord channel @parables_boltnoel

That's all for this post. If this post has helped you, spread the love and help others by sharing it.

See you in the next update

Oldest comments (1)

Collapse
 
oneezy profile image
Justin O'Neill

thanks!