Skip to content

Sveltekit Bootstrap Nav bar

Code PR

Steps

1. Create the navbar in component in components/nav.svelte. You will need to create a folder

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script lang="ts">
  import {
    Collapse,
    Navbar,
    NavbarToggler,
    NavbarBrand,
    Nav,
    NavItem,
    NavLink,
  } from 'sveltestrap/src';
</script>

<Navbar color="light" light expand="md">
  <NavbarBrand href="/">Recipe Site</NavbarBrand>
  <NavbarToggler />
  <Collapse navbar expand="md">
    <Nav class="ms-auto" navbar>
      <NavItem>
        <NavLink href="/login">Login</NavLink>
      </NavItem>
      <NavItem>
        <NavLink>Logout</NavLink>
      </NavItem>
    </Nav>
  </Collapse>
</Navbar>

2. Include the Navbar in __layout.svelte

1
2
3
4
5
6
<script lang="ts">
  import Nav from '../components/nav.svelte';
</script>

...
<Nav />

3. Add the Handle function

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script lang="ts">
  import {
    Collapse,
    Navbar,
    NavbarToggler,
    NavbarBrand,
    Nav,
    NavItem,
    NavLink,
  } from 'sveltestrap/src';

  // variable that control whether mobile menu is open or closed
  let isOpen = false;
</script>

<Navbar color="light" light expand="md">
  <NavbarBrand href="/">Recipe Site</NavbarBrand>
  <NavbarToggler on:click={() => (isOpen = !isOpen)} />
  <Collapse {isOpen} navbar expand="md" on:update="{handleUpdate}">
    <Nav class="ms-auto" navbar>
      <NavItem>
        <NavLink href="/login">Login</NavLink>
      </NavItem>
      <NavItem>
        <NavLink>Logout</NavLink>
      </NavItem>
    </Nav>
  </Collapse>
</Navbar>

4. Add logic to dynamically display the login and logout

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<script lang="ts">
  import {
    Collapse,
    Navbar,
    NavbarToggler,
    NavbarBrand,
    Nav,
    NavItem,
    NavLink,
  } from 'sveltestrap/src';
  import authStore from '../stores/authStore';

  // variable that control whether mobile menu is open or closed
  let isOpen = false;

</script>

<Navbar color="light" light expand="md">
  <NavbarBrand href="/">Recipe Site</NavbarBrand>
  <NavbarToggler on:click={() => (isOpen = !isOpen)} />
  <Collapse {isOpen} navbar expand="md">
    <Nav class="ms-auto" navbar>
      {#if $authStore.firebaseControlled} 
        {#if !$authStore.isLoggedIn}
        <NavItem>
            <NavLink href="/login">Login</NavLink>
        </NavItem>
        {:else}
        <NavItem>
            <NavLink>Logout</NavLink>
        </NavItem>
        {/if} 
      {/if}
    </Nav>
  </Collapse>
</Navbar>

5. Add the logout function

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<script lang="ts">
  import {
    Collapse,
    Navbar,
    NavbarToggler,
    NavbarBrand,
    Nav,
    NavItem,
    NavLink,
  } from 'sveltestrap/src';
  import authStore from '../stores/authStore';
  import firebase from 'firebase/app';

  // variable that control whether mobile menu is open or closed
  let isOpen = false;

  // handles the logout of
  async function logout() {
    await firebase.auth().signOut();
  }
</script>

<Navbar color="light" light expand="md">
  <NavbarBrand href="/">Recipe Site</NavbarBrand>
  <NavbarToggler on:click={() => (isOpen = !isOpen)} />
  <Collapse {isOpen} navbar expand="md">
    <Nav class="ms-auto" navbar>
      {#if $authStore.firebaseControlled}
        {#if !$authStore.isLoggedIn}
          <NavItem>
            <NavLink href="/login">Login</NavLink>
          </NavItem>
        {:else}
          <NavItem>
            <NavLink on:click={logout}>Logout</NavLink>
          </NavItem>
        {/if}
      {/if}
    </Nav>
  </Collapse>
</Navbar>

6. Add Redirect to Login Page

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<script lang="ts">
  import { Row, Col } from 'sveltestrap';
  import firebase from 'firebase/app';
  import authStore from '../stores/authStore';
  import { goto } from '$app/navigation';
  import { onDestroy } from 'svelte';
  async function loginWithGoogle() {
    try {
      const provider = new firebase.auth.GoogleAuthProvider();

      await firebase.auth().signInWithPopup(provider);
    } catch (e) {
      console.log(e);
    }
  }

 authStore.subscribe(async (info) => {
    if (info.isLoggedIn) {
        try {
            await goto('/');
        } catch(e) {
            console.log(e)
        }
    }
  });
</script>

<Row>
  <Col>
    <h1>Login with Google</h1>
  </Col>
</Row>

<Row>
  <Col>
    <img
      on:click={loginWithGoogle}
      src="/login-with-google.png"
      alt="Login With Google"
    />
  </Col>
</Row>

<style>
  img {
    cursor: pointer;
  }
</style>

7. Unsubscribe from authStore when page goes away

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<script lang="ts">
  import { Row, Col } from 'sveltestrap';
  import firebase from 'firebase/app';
  import authStore from '../stores/authStore';
  import { goto } from '$app/navigation';
  import { onDestroy } from 'svelte';
  async function loginWithGoogle() {
    try {
      const provider = new firebase.auth.GoogleAuthProvider();

      await firebase.auth().signInWithPopup(provider);
    } catch (e) {
      console.log(e);
    }
  }

  const sub =  authStore.subscribe(async (info) => {
    if (info.isLoggedIn) {
        try {
            await goto('/');
        } catch(e) {
            console.log(e)
        }
    }
  });

  onDestroy(() => {
    sub();
  });
</script>

<Row>
  <Col>
    <h1>Login with Google</h1>
  </Col>
</Row>

<Row>
  <Col>
    <img
      on:click={loginWithGoogle}
      src="/login-with-google.png"
      alt="Login With Google"
    />
  </Col>
</Row>

<style>
  img {
    cursor: pointer;
  }
</style>

8. Cleanup index.svelte file

1
2
3
4
5
6
7
8
9
<script lang="ts">
  import { Row, Col, Button } from 'sveltestrap';
</script>

<Row>
  <Col>
    <h1>Welcome to the recipe site</h1>
  </Col>
</Row>

Resources