Custom titlebar in Nuxt with Tauri with controls
Tags: nuxt, tauri, tutorial, programming
Published: 2023-09-03 18:32:46

![titlebar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kcthzd1k2tla65t34sdh.png)



Custom titlebar in [Nuxt](https://nuxt.com/) and [Tauri](https://tauri.app/)? Not to hard! I will use the code from the previous tutorial, but you can use it in any existing project without any problems. And like always, everything is on [GitHub](https://github.com/Waradu/nuxt-tauri-tutorial).

First Step: Create a `components` folder and a `Titlebar.vue` file inside. Inside the newly created file, we need a `<template>`, `<script setup lang="ts">`, `<style lang="scss">`:
```vue
<template>
</template>

<script setup lang="ts">
</script>

<style lang="scss">
</style>
```

In the template, section, we add a div with class titlebar and style it, so it is visible:
```vue
<template>
  <div data-tauri-drag-region class="titlebar">
  </div>
</template>

<style lang="scss">
.titlebar {
  background-color: rgba(0,0,0,50%);
  height: 40px;
  user-select: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
</style>
```
*You can make any object to a draggable region with `data-tauri-drag-region`.*

But before it works, you'll need to:
Add this to the allowlist in `src-tauri/tauri.conf.json`:
```json
{
  ...
  "tauri": {
    "allowlist": {
      "window": {
        "all": true
      }
    }
  },
  ...
}
```
and add the Titlebar component to `app.vue`:
```vue
<template>
  <Titlebar />
</template>
```

To add controls, add the following to the titlebar div, add some typescript and change some styles (you can customize it as you like):
```vue
<template>
  <div data-tauri-drag-region class="titlebar">
    <div class="titlebar-button" id="titlebar-minimize" @click="minimize">
      <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M6 12H18" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
      </svg>
    </div>

    <div class="titlebar-button" id="titlebar-maximize" @click="toggleMaximize">
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M2 9V6.5C2 4.01 4.01 2 6.5 2H9" stroke="#ffffff" stroke-width="2" stroke-linecap="round"
          stroke-linejoin="round" />
        <path d="M15 2H17.5C19.99 2 22 4.01 22 6.5V9" stroke="#ffffff" stroke-width="2" stroke-linecap="round"
          stroke-linejoin="round" />
        <path d="M22 16V17.5C22 19.99 19.99 22 17.5 22H16" stroke="#ffffff" stroke-width="2" stroke-linecap="round"
          stroke-linejoin="round" />
        <path d="M9 22H6.5C4.01 22 2 19.99 2 17.5V15" stroke="#ffffff" stroke-width="2" stroke-linecap="round"
          stroke-linejoin="round" />
      </svg>
    </div>

    <div class="titlebar-button" id="titlebar-close" @click="close">
      <svg width="18" height="18" viewBox="0 0 24 24" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
        xmlns="http://www.w3.org/2000/svg">
        <g id="close" fill-opacity="1">
          <path d="M0 0L24 0L24 24L0 24L0 0Z" id="close" fill="none" fill-rule="evenodd" stroke="none" />
          <g id="close">
            <path d="M2 22L22 2" id="Vector" fill="none" fill-rule="evenodd" stroke="#fff" stroke-width="2"
              stroke-linecap="round" stroke-linejoin="round" />
            <path d="M22 22L2 2" id="Vector" fill="none" fill-rule="evenodd" stroke="#fff" stroke-width="2"
              stroke-linecap="round" stroke-linejoin="round" />
            <path d="M24 0L24 24L0 24L0 0L24 0Z" id="Vector" fill="none" fill-rule="evenodd" stroke="none" />
          </g>
        </g>
      </svg>
    </div>
  </div>
</template>

<style lang="scss">
.titlebar {
  background-color: rgba(0,0,0,50%);
  height: 40px;
  user-select: none;
  display: flex;
  justify-content: flex-end;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  align-items: center;
  padding-inline: 2px;
}

.titlebar-button {
  display: flex;
  justify-content: center;
  align-items: center;
  fill: white;
  width: 32px;
  height: 32px;
  border-radius: 3px;
  margin-inline: 3px;
  padding: 0;
}

.titlebar-button:last-child {
  margin-right: 6px;
}

.titlebar-button:hover {
  background: #303030;
}

#titlebar-close:hover {
  background-color: #e06c75;
}
</style>

<script setup lang="ts">
import { appWindow } from "@tauri-apps/api/window";

function minimize() { appWindow.minimize(); }
function toggleMaximize() { appWindow.toggleMaximize() }
function close() { appWindow.close() }
</script>
```

It should now look like this:

![final result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m6o7qayccp9rk9ye1ozg.png)