咨询热线:15911225507
龙霄
登录
首页-所有文章-Nuxt.js英文-正文

Integrating AI APIs in Nuxt 3 for Smart Content Generation and Multilingual Translation

龙霄龙霄
Nuxt.js英文
6天前
0
0
18

With the rapid advancement of large language model (LLM) technology, more and more web applications are integrating AI capabilities—from intelligent customer support and content summarization to automatic translation. AI is reshaping how frontend development works. For developers building full-stack applications with Nuxt 3, knowing how to safely and efficiently call AI APIs within a project is a topic worth exploring in depth. This article will guide you step by step through integrating OpenAI-compatible APIs in a Nuxt 3 project to implement smart content generation and multilingual translation.

1. Why Server-Side Calls

When calling AI APIs in a Nuxt 3 project, the primary consideration is security. All major AI services (OpenAI, Claude, DeepSeek, etc.) require API Key authentication. If you hardcode the API Key in frontend code, anyone can obtain your key through browser developer tools, causing serious security risks and cost leakage.

Nuxt 3's server/api directory provides the perfect solution: API routes run on the server side (Nitro engine), the API Key is stored in .env environment variables, and the frontend calls its own endpoints via $fetch. The server then forwards requests to the AI service. This way, the API Key is never exposed to the client.

2. Environment Setup

First, create a .env file in your Nuxt 3 project root:

NUXT_OPENAI_API_KEY=sk-your-api-key-here
NUXT_OPENAI_BASE_URL=https://api.openai.com/v1
NUXT_AI_MODEL=gpt-4o-mini

No additional configuration is needed in nuxt.config.ts—Nitro automatically reads environment variables prefixed with NUXT_ and exposes them via useRuntimeConfig() on the server side.

3. Creating the AI Service Layer

For code reusability and maintainability, we first create a generic AI service wrapper. In server/utils/ai.ts:

interface ChatMessage {
  role: 'system' | 'user' | 'assistant'
  content: string
}

interface ChatOptions {
  messages: ChatMessage[]
  temperature?: number
  maxTokens?: number
  stream?: boolean
}

export async function chatCompletion(options: ChatOptions) {
  const config = useRuntimeConfig()
  
  const response = await $fetch(`${config.openaiBaseUrl}/chat/completions`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${config.openaiApiKey}`,
      'Content-Type': 'application/json',
    },
    body: {
      model: config.aiModel,
      messages: options.messages,
      temperature: options.temperature ?? 0.7,
      max_tokens: options.maxTokens ?? 2048,
      stream: options.stream ?? false,
    },
  })
  
  return response
}

4. Implementing the Content Generation API Route

Create server/api/ai/generate.post.ts:

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const { prompt, systemPrompt } = body

  if (!prompt) {
    throw createError({
      statusCode: 400,
      message: 'The prompt parameter is required',
    })
  }

  try {
    const result = await chatCompletion({
      messages: [
        { role: 'system', content: systemPrompt || 'You are a professional technical content creator.' },
        { role: 'user', content: prompt },
      ],
      temperature: 0.8,
    })

    return {
      success: true,
      content: result.choices[0].message.content,
      usage: result.usage,
    }
  } catch (error: any) {
    throw createError({
      statusCode: 500,
      message: error.message || 'AI service call failed',
    })
  }
})

5. Implementing Streaming Responses (SSE)

For content generation scenarios, streaming responses significantly improve user experience—users can see text being generated word by word rather than waiting several seconds for a one-shot display. Create server/api/ai/stream.post.ts:

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const { prompt, systemPrompt } = body
  const config = useRuntimeConfig()

  setHeader(event, 'Content-Type', 'text/event-stream')
  setHeader(event, 'Cache-Control', 'no-cache')
  setHeader(event, 'Connection', 'keep-alive')

  const response = await fetch(
    `${config.openaiBaseUrl}/chat/completions`,
    {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${config.openaiApiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        model: config.aiModel,
        messages: [
          { role: 'system', content: systemPrompt || 'You are a professional assistant.' },
          { role: 'user', content: prompt },
        ],
        stream: true,
      }),
    }
  )

  const reader = response.body?.getReader()
  if (!reader) throw createError({ statusCode: 500 })

  const decoder = new TextDecoder()
  let buffer = ''

  while (true) {
    const { done, value } = await reader.read()
    if (done) {
      sendEventStream(event, { data: '[DONE]' })
      break
    }

    buffer += decoder.decode(value, { stream: true })
    const lines = buffer.split('n')
    buffer = lines.pop() || ''

    for (const line of lines) {
      if (line.startsWith('data: ') && line !== 'data: [DONE]') {
        try {
          const parsed = JSON.parse(line.slice(6))
          const content = parsed.choices[0]?.delta?.content
          if (content) {
            sendEventStream(event, { data: content })
          }
        } catch {}
      }
    }
  }
})

6. Frontend Vue Component Integration

Create a reusable AI content generation component:

<script setup lang="ts">
const prompt = ref('')
const generatedContent = ref('')
const isLoading = ref(false)
const isStreaming = ref(false)

async function generateContent() {
  if (!prompt.value.trim()) return
  
  isLoading.value = true
  generatedContent.value = ''
  
  try {
    const data = await $fetch('/api/ai/generate', {
      method: 'POST',
      body: { prompt: prompt.value },
    })
    generatedContent.value = data.content
  } catch (error) {
    console.error('Generation failed:', error)
  } finally {
    isLoading.value = false
  }
}

async function generateStream() {
  if (!prompt.value.trim()) return
  
  isStreaming.value = true
  generatedContent.value = ''
  
  const eventSource = new EventSource(
    `/api/ai/stream?${new URLSearchParams({ prompt: prompt.value })}`
  )
  
  eventSource.onmessage = (event) => {
    if (event.data === '[DONE]') {
      eventSource.close()
      isStreaming.value = false
      return
    }
    generatedContent.value += event.data
  }
  
  eventSource.onerror = () => {
    eventSource.close()
    isStreaming.value = false
  }
}
</script>

7. Implementing Multilingual Translation

Based on the AI service layer above, implementing multilingual translation is straightforward. Create server/api/ai/translate.post.ts:

export default defineEventHandler(async (event) => {
  const { text, targetLang, sourceLang } = await readBody(event)

  const langMap: Record<string, string> = {
    'zh-cn': 'Simplified Chinese',
    'zh-tw': 'Traditional Chinese',
    'en': 'English',
    'ja': 'Japanese',
  }

  const result = await chatCompletion({
    messages: [
      {
        role: 'system',
        content: `You are a professional translator. Translate the following${sourceLang ? ' ' + (langMap[sourceLang] || sourceLang) : ''} text into ${langMap[targetLang] || targetLang}. Return only the translation, without any explanations.`,
      },
      { role: 'user', content: text },
    ],
    temperature: 0.3,
  })

  return {
    success: true,
    translation: result.choices[0].message.content,
    sourceLang,
    targetLang,
  }
})

8. Error Handling and Rate Limiting

In production environments, AI API calls can fail for various reasons—network timeouts, rate limits, insufficient balance, etc. We need robust error handling mechanisms.

Add retry logic in server/utils/ai.ts:

export async function chatCompletionWithRetry(
  options: ChatOptions,
  maxRetries = 3
) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await chatCompletion(options)
    } catch (error: any) {
      if (error.statusCode === 429) {
        // Rate limited — wait and retry
        const retryAfter = error.headers?.get('retry-after') || 5
        await new Promise(r => setTimeout(r, retryAfter * 1000))
        continue
      }
      if (i === maxRetries - 1) throw error
      await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)))
    }
  }
}

It's also recommended to set request body size limits in the Nitro configuration:

// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    routeRules: {
      '/api/ai/**': {
        maxBodySize: '1mb',
      },
    },
  },
})

9. Summary

Through Nuxt 3's Server API routes, we've integrated AI capabilities in a secure and efficient manner. Key takeaways:

  • Security: API Keys are stored in server-side environment variables, never exposed to the client
  • Streaming Responses: SSE enables real-time content generation, enhancing user experience
  • Reusable Architecture: Through a service layer abstraction, content generation and translation share the same AI calling logic
  • Robustness: Exponential backoff retry strategy handles rate limiting and network anomalies

This architecture has been running reliably across multiple projects at Salong Network—whether automatically generating technical articles and product descriptions, or handling multilingual site content translation, it performs efficiently. I hope this article helps you successfully integrate AI capabilities into your Nuxt 3 projects.

标签:
本文来源萨龙网络,经授权后由龙霄发布,观点不代表龙霄的立场,转载请联系原作者。
龙霄

龙霄

Lv1Rec2
以 Nuxt.js 之力,焕新 WordPress 体验
197.63W1214.22W1.07W
加载中…
分享:
1
Nuxt 3 项目中集成 AI API 实现智能内容生成与多语言翻译
Nuxt 3 项目中集成 AI API 实现智能内容生成与多语言翻译上一篇
Nuxt.js Headless WordPress 项目中的数据缓存优化策略下一篇
Nuxt.js Headless WordPress 项目中的数据缓存优化策略
相关文章
总数:0
龙霄
没有相关内容
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
龙霄
没有相关内容