Easily integrate Bluesky login and AT Protocol authentication into your Nuxt.js app.
nuxt-atproto
is a Nuxt.js module that simplifies the OAuth authentication via AT Protocol.
It handles the login and the session management using the @atproto/oauth-client
library,
providing public and authenticated agents for seamless interaction with AT Protocol services.
- SSR-friendly login via Bluesky and AT Protocol with automatic service endpoint resolution.
- Allow logins without specifying the handle, enabling account selection from PDS interface.
- Simple access to sign-in, sign-out, public and private agents from
useAtproto
composable. - Access to the underlying client and session with
$atproto
provided by the plugin. - Dynamically generates
client-metadata.json
when the Nuxt.js app starts.
Install the module via npm:
npm install nuxt-atproto
Register the module in your nuxt.config.js
:
export default defineNuxtConfig({
modules: ['nuxt-atproto']
})
You can configure nuxt-atproto
in your nuxt.config.ts
file under the atproto
key.
The following options are available with their default values:
defineNuxtConfig({
modules: ['nuxt-atproto'],
atproto: {
serviceEndpoint: {
private: 'https://bsky.social',
public: 'https://public.api.bsky.app'
},
oauth: {
clientMetadata: {
// url of your remote client_metadata.json, leave the field empty
// to let `nuxt-atproto` generate a local /public/client_metadata.json
remote: '',
// configuration for the local client_metadata.json
local: {
client_id: 'https://nuxt-atproto.pages.dev/client-metadata.json',
client_name: 'nuxt-atproto',
client_uri: 'https://nuxt-atproto.pages.dev',
logo_uri: 'https://nuxt-atproto.pages.dev/logo.png',
tos_uri: 'https://nuxt-atproto.pages.dev',
policy_uri: 'https://nuxt-atproto.pages.dev',
redirect_uris: ['https://nuxt-atproto.pages.dev'],
scope: "atproto transition:generic",
grant_types: ["authorization_code", "refresh_token"],
response_types: ["code"],
token_endpoint_auth_method: 'none',
application_type: 'web',
dpop_bound_access_tokens: true
}
},
signInOptions: {
state: '',
prompt: 'login',
scope: 'atproto',
ui_locales: 'en',
},
},
debug: true,
}
})
You must configure the atproto.oauth.clientMetadata
with in your nuxt.config.ts
,
especially client_id
and redirect_uris
, for the authentication flow to work correctly.
If you don't provide a remote URL in the module options, when Nuxt.js starts it will create a client-metadata.json
in your public
folder.
Using a local client-metadata.json
generally offers a faster user experience compared to fetching it from a remote URL.
<script setup lang="ts">
const atproto = useAtproto()
</script>
<template>
<div>
<Button @click="atproto.signIn()">
Sign-in with ATProto
</Button><br />
<Button @click="atproto.signInWithHandle('dxlliv.bsky.social')">
Sign-in with ATProto using dxlliv.bsky.social
</Button><br />
<Button @click="atproto.signInWithHandle()">
Sign-in with ATProto using your handle (prompt)
</Button>
<Button @click="atproto.restore('did:plc:2pkidgvfnbxx7sq3shporxij')">
Restore dxlliv.bsky.social session
</Button>
</div>
<template v-if="atproto.agent.account">
<div>logged with: {{atproto.agent.account.assertDid}}</div>
<Button @click="atproto.signOut()">
Sign-out
</Button>
</template>
</template>
A composable provided by nuxt-atproto
that offers methods for user authentication and session management, including authenticating, signing out and session restore.
<script setup lang="ts">
const atproto = useAtproto()
</script>
Parameters:
-
service
(optional): Override the service endpoint of the public agent. -
fetch
(optional): A custom fetch implementation.
Initiates the standard ATProto sign-in flow redirecting the user for authentication.
<Button @click="atproto.signIn()">
Sign-in with ATProto
</Button>
Parameters:
-
serviceEndpoint
: (optional) The specific ATProto service endpoint to use for sign-in. -
options
: (optional) Additional options to configure the sign-in process.
// options
{
state: "",
prompt: "login",
scope: "atproto",
ui_locales: "en"
}
Returns: A Promise that might not directly resolve due to the redirection to the ATProto service.
Initiates the ATProto sign-in flow using the user's AT Protocol handle.
The user will be prompted to enter their handle on the ATProto service if you omit the handle.
<Button @click="atproto.signInWithHandle()">
Sign-in with ATProto
</Button>
Parameters:
-
handle
: (optional) The AT Protocol handle of the user. -
options
: (optional) Additional options to configure the sign-in process.
Returns: A Promise that might not directly resolve due to the redirection to the ATProto service.
Restore the user account associated with the provided Decentralized Identifier (DID).
<Button @click="atproto.restore('did:plc:2pkidgvfnbxx7sq3shporxij')">
Restore dxlliv.bsky.social
</Button>
Parameters:
-
handle
: (optional) The Decentralized Identifier (DID) of the account to be restored.
Returns: A Promise that resolves when the restoration process is complete.
Logs out the currently authenticated user and clears the stored session data.
<Button @click="atproto.signOut()">
Sign-out
</Button>
Returns: A Promise that resolves when the restoration process is complete.
Indicates whether the user is currently authenticated.
const atproto = useAtproto()
if (!atproto.isLogged()) {
return console.log('User is not logged in')
}
console.log('User is authenticated')
Returns: Returns a boolean indicating whether the user is authenticated.
Retrieves the current session from the Nuxt application context.
const atproto = useAtproto()
if (atproto.isLogged()) {
const session = atproto.getSession()
console.log('User is logged in', session.sub)
}
Returns: Returns the current AT Protocol OAuth Browser session.
A composable provided by nuxt-atproto
that offers methods for user authentication and session management, including authenticating, signing out and session restore.
<script setup lang="ts">
const agent = useAgent('public')
</script>
Parameters:
-
service
(optional): Choose betweenpublic
,private
or a custom service endpoint. -
fetch
(optional): A custom fetch implementation.
This package is released under the MIT license.