본문 바로가기
Documentation menu

JavaScript / TypeScript / SDK REFERENCE

Vue / Nuxt SDK Guide

The official Vue SDK for sending Kakao Alimtalk, Brand Message and SMS from Nuxt server routes — server-side only.

이 문서의 목차
패키지
@sendgo/vue
언어
JavaScript / TypeScript
레지스트리
npm
설치
npm install @sendgo/vue

The official Vue SDK for sending Kakao Alimtalk, Brand Message and SMS from Nuxt

@sendgo/vue wraps the @sendgo/node core as a Vue plugin that provides the client through Vue's injection system.

Server-side only. Your access key and secret key must never reach the browser. Register the plugin as a server-only Nuxt plugin, or use the client directly inside a server/api route. Never register it in a universal plugin.

Requires Vue 3.4+ and Nuxt 3+.


Install

npm install @sendgo/vue

The core @sendgo/node comes along as a dependency.


Register the plugin (Nuxt, server-only)

The .server.ts suffix is what keeps the keys out of the client bundle:

// plugins/sendgo.server.ts
import { SendgoPlugin } from '@sendgo/vue';

export default defineNuxtPlugin((app) => {
  app.vueApp.use(SendgoPlugin, {
    accessKey: process.env.SENDGO_ACCESS_KEY!,
    secretKey: process.env.SENDGO_SECRET_KEY!,
    kakaoSenderKey: process.env.SENDGO_KAKAO_SENDER_KEY,
    smsSenderKey: process.env.SENDGO_SMS_SENDER_KEY,
    apiVersion: 'v2',
  });
});

Use the injected client

<script setup lang="ts">
import { inject } from 'vue';
import { SENDGO_KEY } from '@sendgo/vue';
import type Sendgo from '@sendgo/node';

// Only resolves during SSR — the plugin is server-only by design.
const sendgo = inject<Sendgo>(SENDGO_KEY);

await sendgo?.alimtalk.send({
  templateCode: 'ORDER_CONFIRM_001',
  contacts: [{ contact: '01012345678', var1: 'ORD-001' }],
});
</script>

SENDGO_KEY provides the whole core client, so every channel is available on it:

Property Channel
sendgo.alimtalk Kakao Alimtalk
sendgo.friendtalk Kakao Friendtalk
sendgo.brandMessage Kakao Brand Message (v2 only)
sendgo.sms SMS / LMS / MMS

For anything triggered by a user action, a server route is clearer than SSR injection — the browser calls your endpoint, and the keys stay on the server:

// server/api/notify.post.ts
import { Sendgo, SendgoError } from '@sendgo/vue';

const sendgo = new Sendgo({
  accessKey: process.env.SENDGO_ACCESS_KEY!,
  secretKey: process.env.SENDGO_SECRET_KEY!,
  kakaoSenderKey: process.env.SENDGO_KAKAO_SENDER_KEY,
  apiVersion: 'v2',
});

export default defineEventHandler(async (event) => {
  const { phone, orderNo } = await readBody(event);

  try {
    await sendgo.alimtalk.send({
      templateCode: 'ORDER_CONFIRM_001',
      contacts: [{ contact: phone, var1: orderNo }],
    });

    return { ok: true };
  } catch (error) {
    if (error instanceof SendgoError) {
      // Log the provider detail; return a generic status to the caller.
      console.error(`Sendgo ${error.statusCode} [${error.errorCode}]: ${error.message}`);

      throw createError({
        statusCode: error.statusCode >= 500 ? 502 : 400,
        statusMessage: 'Message delivery failed',
      });
    }

    throw error;
  }
});

The client is constructed once at module scope, so the token cache is reused across requests.


Brand Message

Friendtalk was discontinued on 2025-12-31. Since 2026-01-01 Kakao delivers Friendtalk requests as Brand Message (free-form) automatically. friendtalk still works and is still the only path for free-form FT/FI/FW to individual recipients — use Brand Message for template-based rich types (FL/FC/FM/FP/FA), non-friend targeting (N/I) and broadcasts (F). Brand Message is the successor channel to Friendtalk: it reaches recipients who are not channel friends (targeting: 'N') and can broadcast to every consenting channel friend (targeting: 'F'). Message types map one-to-one with Friendtalk (FT→BT, FI→BI, FW→BW, FL→BL, FC→BC, FM→BM, FP→BP, FA→BA) — pass the Friendtalk code and the server converts it.

v2 only. Set apiVersion: 'v2'.

// server/api/campaign.post.ts
export default defineEventHandler(async (event) => {
  const { mode, phone } = await readBody(event);

  if (mode === 'broadcast') {
    // No recipient list — Kakao expands the audience
    return sendgo.brandMessage.broadcast({
      messageType: 'FW',
      friendTemplateUuid: '9cd5460b-6458-4edc-9b11-c26d3013c340',
    });
  }

  return sendgo.brandMessage.send({
    targeting: 'M',
    messageType: 'FL',
    friendTemplateUuid: '9cd5460b-6458-4edc-9b11-c26d3013c340',
    contacts: [{ contact: phone, var1: '29,000 KRW' }],
  });
});
// server/api/campaigns.get.ts — a broadcast is asynchronous upstream, so poll
export default defineEventHandler(async (event) => {
  const { campaignId } = getQuery(event);

  return campaignId
    ? sendgo.brandMessage.campaign(String(campaignId))
    : sendgo.brandMessage.campaigns({ count: 10 });
});

Client-side composable

useAlimtalk wraps a call to your own server route with pending/error state. It returns { send, loading, error, data, reset }:

<script setup lang="ts">
import { useAlimtalk } from '@sendgo/vue';

const { send, loading, error, data, reset } = useAlimtalk();

const notify = () => send({
  templateCode: 'ORDER_CONFIRM_001',
  contacts: [{ contact: '01012345678', var1: 'ORD-001' }],
});
</script>

<template>
  <button :disabled="loading" @click="notify">
    {{ loading ? 'Sending…' : 'Send' }}
  </button>
  <p v-if="error" role="alert">
    {{ error.message }}
    <button @click="reset">Dismiss</button>
  </p>
  <p v-else-if="data">Sent.</p>
</template>

Plain Vue 3 (no Nuxt)

Without Nuxt there is no server/client split, so the plugin belongs in a Node process — an Express or Fastify backend rendering with @vue/server-renderer, or a worker. Do not register it in a browser-only app.

import { createSSRApp } from 'vue';
import { SendgoPlugin } from '@sendgo/vue';

const app = createSSRApp(App);
app.use(SendgoPlugin, {
  accessKey: process.env.SENDGO_ACCESS_KEY!,
  secretKey: process.env.SENDGO_SECRET_KEY!,
  apiVersion: 'v2',
});

Types

Every request shape is re-exported from the core:

import type {
  AlimtalkParams,
  FriendtalkParams,
  BrandMessageParams,
  BrandMessageListParams,
  BrandMessageTargeting,
  SmsParams,
  Contact,
  SendgoConfig,
  SendgoResponse,
} from '@sendgo/vue';

Sendgo (the client class) and SendgoError are exported as values, not just types.


Short URL

Short URLs shrink the links in your message body and count whether they were actually clicked. SMS is billed by byte, so a shorter link leaves more room for copy.

v2 only.

Shortening the same target URL again returns the existing link. Pass forceNew to mint a new code when you want per-campaign reaction figures kept separate.

deactivate does not delete the link — it only stops the redirect. Use it when a link in an already-sent message has to be killed; the accumulated stats stay, and visitors to a stopped link get 410 Gone.

// server/api/shorten.post.ts
export default defineEventHandler(async (event) => {
  const { targetUrl } = await readBody(event);

  const created = await sendgo.shortUrl.create({ targetUrl });

  return { shortUrl: created.data.shortUrl, code: created.data.code };
});

stats returns a daily series (daily) plus breakdowns by device (byDevice), referrer (byReferer) and country (byCountry). The daily series is read from a pre-aggregated table, so response time stays flat no matter how many clicks accumulate.


Package information

Getting your API keys

Sign in to Sendgo and open API/SDK → API integration to issue an access key and secret key. Register a Kakao sender profile under Kakao channel to get your kakaoSenderKey, and a caller ID under Sender numbers for SMS.

이 패키지로 할 수 있는 것

관련 패키지

Focus on building. Leave messaging to Sendgo.Back to top ↑