What's new in `svelte-kit, 1.0.0-next.445`: (group) layout
Tags: svelte, sveltekit, javascript, news
Published: 2022-08-29 16:58:00

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](https://github.com/sveltejs/kit/discussions/) and read the [CHANGELOG.md](https://github.com/sveltejs/kit/blob/05e8240150da446f6cd3c1f0feb4447408b2b43b/packages/kit/CHANGELOG.md) to stay updated on the breaking changes

## What's Changed

- (group) layout replaces named-layout [#6124](https://github.com/sveltejs/kit/discussions/6124)
  - [#6124](https://github.com/sveltejs/kit/discussions/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](https://github.com/sveltejs/kit/pull/4388). See [CHANGELOG.md](https://github.com/sveltejs/kit/blob/05e8240150da446f6cd3c1f0feb4447408b2b43b/packages/kit/CHANGELOG.md#100-next306)

## 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:

````tree
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
```

Will give us the following routes:
``` text
/
/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
```

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
``` tree
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
```

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
``` log
Error:  and (dashbaord) occupy the same route
```
- 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`.

- A  `+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
``` bash
rm -rf node_modules .sveltekit
rm package-lock.json # change it as per your package manager `pnpm` or `yarn`
```
- And reinstall the packages again using your preferred  package manager
``` bash
npm install
```
This is necessary in order to ensure that you have the latest versions of the dependencies.

- [npm-check-updates](https://www.npmjs.com/package/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](https://svelte.dev/chat) `@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