Skip to content

Marko

This guide shows how to integrate gau with Marko 6 and Marko Run, using GitHub as an example.


  1. Complete the Getting Started guide.

    Create your auth instance in src/server/auth.ts. For a persistent database, follow the Drizzle guide.

    For GitHub, set the callback URL to http://localhost:3000/api/auth/callback/github during development.

  2. Export the Marko Run helpers alongside your auth instance:

    src/server/auth.ts
    import { MarkoRunAuth } from '@rttnd/gau/marko-run'
    // After creating your auth instance:
    export const gau = MarkoRunAuth(auth)

    Create a catch-all route for the auth endpoints.

    src/routes/api/auth/$$gau/+handler.ts
    import { gau } from '../../../../server/auth'
    export const GET = Run.GET((ctx) => gau.handle(ctx.request))
    export const POST = Run.POST((ctx) => gau.handle(ctx.request))
    export const OPTIONS = Run.OPTIONS((ctx) => gau.handle(ctx.request))
  3. Add middleware to refresh the session cookie when needed.

    src/routes/+middleware.ts
    import { gau } from '../server/auth'
    export default Run.ALL((ctx, next) => gau.refresh(ctx.request, () => next()))
  4. Pass the session from your page handler:

    src/routes/+handler.ts
    import { gau } from '../server/auth'
    export const GET = Run.GET((ctx, next) => next({ session: gau.getSession(ctx.request) }))

    Use <await> to read the session in your page. Use a link to sign in and a form to sign out:

    src/routes/+page.marko
    <await|session|=$global.data.session>
    <if=session.user>
    <p>Welcome, ${session.user.name}!</p>
    <form method="post" action="/api/auth/signout?redirectTo=/">
    <button>Sign out</button>
    </form>
    </if>
    <else>
    <a href="/api/auth/github?redirectTo=/account">Sign in with GitHub</a>
    </else>
    </await>

    getSession(request) returns data that can be sent to the browser. Use getServerSession(request) only when you need account tokens on the server.

  5. Add the client tag when you need reactive session data. This is optional for server-rendered pages.

    src/routes/+page.marko
    import GauAuth from "@rttnd/gau/client/marko/Auth.marko";
    <await|session|=$global.data.session>
    <GauAuth/auth session=session/>
    <p>${auth.session.user?.name}</p>
    <button onClick() { auth.refresh(); } disabled=auth.isLoading>
    Refresh session
    </button>
    </await>

    Pass the returned auth value to components that need it. No context provider is required.

    The tag starts with the supplied session and accepts later session updates. Without a session, it loads one in the browser.

    After signing out through JavaScript, navigate to a fresh page to update content rendered by the server. Use normal browser navigation for auth changes; Marko’s persisted pages are still under development.

  6. Check the session before rendering the page or loading private data.

    src/routes/account/+handler.ts
    import { gau } from '../../server/auth'
    export const GET = Run.GET(async (ctx, next) => {
    const session = await gau.getSession(ctx.request)
    if (!session.user)
    return ctx.redirect('/')
    return next({ session })
    })
    • Directorysrc
      • Directoryserver
        • auth.ts
      • Directoryroutes
        • Directoryapi
          • Directoryauth
            • Directory$$gau
              • +handler.ts
        • Directoryaccount
          • +handler.ts
        • +handler.ts
        • +middleware.ts
        • +page.marko
    • package.json
    • vite.config.ts