Send SMS messages in your Next.js applications using the Text.lk SMS Gateway API in Sri Lanka. This guide provides simple, production-ready code examples for Next.js to get you started quickly.
Prerequisites #
- Next.js project (App Router or Pages Router)
- Text.LK account with API token
- Basic knowledge of React and Next.js
Getting Your API Token #
- Sign up at Text.lk
- Navigate to your dashboard
- Copy your API token from the API settings
API Reference #
Text.LK Send SMS Endpoint #
GET https://app.text.lk/api/http/sms/send
Parameters: #
recipient
(required): Phone number with country code (e.g., 94710000000)sender_id
(required): Your brand name or sender IDmessage
(required): SMS content (max 160 characters for single SMS)api_token
(required): Your Text.LK API token
Example Success Response: #
{
"status": "success",
"message": "Your message was successfully delivered",
"data": {
"uid": "689f012753f11",
"to": "94771234567",
"from": "TextLKDemo",
"message": "This is test message",
"status": "Delivered",
"cost": "1",
"sms_count": 1
}
}
Example Error Response: #
{
"status": "error",
"message": "A human-readable description of the error."
}
Quick Setup #
Environment Variables #
Create a .env.local
file in your project root:
TEXTLK_API_TOKEN=your_api_token_here
TEXTLK_SENDER_ID=YourBrandName
Implementation Methods #
Method 1: Server-Side API Route (Recommended) #
Create an API route to handle SMS sending securely.
File: app/api/textlk/send/route.js
(App Router)
import { NextResponse } from 'next/server';
export async function POST(request) {
try {
const { recipient, message, senderId } = await request.json();
const response = await sendTextLKSMS({
recipient,
message,
senderId: senderId || process.env.TEXTLK_SENDER_ID
});
return NextResponse.json(response);
} catch (error) {
return NextResponse.json(
{ error: 'Failed to send SMS' },
{ status: 500 }
);
}
}
async function sendTextLKSMS({ recipient, message, senderId }) {
const url = new URL('https://app.text.lk/api/http/sms/send');
url.searchParams.append('recipient', recipient);
url.searchParams.append('sender_id', senderId);
url.searchParams.append('message', message);
url.searchParams.append('api_token', process.env.TEXTLK_API_TOKEN);
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`Text.LK API error: ${response.status}`);
}
return await response.json();
}
For Pages Router: pages/api/textlk/send.js
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const { recipient, message, senderId } = req.body;
const response = await sendTextLKSMS({
recipient,
message,
senderId: senderId || process.env.TEXTLK_SENDER_ID
});
res.status(200).json(response);
} catch (error) {
res.status(500).json({ error: 'Failed to send SMS' });
}
}
async function sendTextLKSMS({ recipient, message, senderId }) {
const url = new URL('https://app.text.lk/api/http/sms/send');
url.searchParams.append('recipient', recipient);
url.searchParams.append('sender_id', senderId);
url.searchParams.append('message', message);
url.searchParams.append('api_token', process.env.TEXTLK_API_TOKEN);
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`Text.LK API error: ${response.status}`);
}
return await response.json();
}
Method 2: Custom Hook for Client Components #
Create a reusable hook for SMS functionality.
File: hooks/useTextLK.js
import { useState } from 'react';
export function useTextLK() {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const sendSMS = async ({ recipient, message, senderId }) => {
setLoading(true);
setError(null);
try {
const response = await fetch('/api/textlk/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
recipient,
message,
senderId
}),
});
if (!response.ok) {
throw new Error('Failed to send SMS');
}
const result = await response.json();
return result;
} catch (err) {
setError(err.message);
throw err;
} finally {
setLoading(false);
}
};
return { sendSMS, loading, error };
}
Usage Examples #
Simple SMS Form Component #
'use client'; // Only needed for App Router
import { useState } from 'react';
import { useTextLK } from '../hooks/useTextLK';
export default function SMSForm() {
const [recipient, setRecipient] = useState('');
const [message, setMessage] = useState('');
const [success, setSuccess] = useState(false);
const { sendSMS, loading, error } = useTextLK();
const handleSubmit = async (e) => {
e.preventDefault();
setSuccess(false);
try {
await sendSMS({
recipient,
message,
senderId: 'YourBrand' // Optional: will use env variable if not provided
});
setSuccess(true);
setRecipient('');
setMessage('');
} catch (err) {
console.error('SMS send failed:', err);
}
};
return (
<form onSubmit={handleSubmit} className="max-w-md mx-auto p-6">
<h2 className="text-2xl font-bold mb-4">Send SMS with Text.LK</h2>
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
Phone Number (with country code)
</label>
<input
type="tel"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
placeholder="94710000000"
className="w-full p-2 border rounded"
required
/>
</div>
<div className="mb-4">
<label className="block text-sm font-medium mb-2">
Message
</label>
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Your message here..."
className="w-full p-2 border rounded h-24"
required
/>
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 disabled:opacity-50"
>
{loading ? 'Sending...' : 'Send SMS'}
</button>
{error && (
<div className="mt-4 p-2 bg-red-100 text-red-700 rounded">
Error: {error}
</div>
)}
{success && (
<div className="mt-4 p-2 bg-green-100 text-green-700 rounded">
SMS sent successfully!
</div>
)}
</form>
);
}
Server Action (App Router Only) #
For server-side SMS sending without API routes:
File: lib/textlk-actions.js
'use server';
export async function sendTextLKNotification(recipient, message) {
try {
const url = new URL('https://app.text.lk/api/http/sms/send');
url.searchParams.append('recipient', recipient);
url.searchParams.append('sender_id', process.env.TEXTLK_SENDER_ID);
url.searchParams.append('message', message);
url.searchParams.append('api_token', process.env.TEXTLK_API_TOKEN);
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`Text.LK API error: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Text.LK SMS failed:', error);
throw new Error('Failed to send SMS notification');
}
}
Utility Functions #
Phone Number Validation #
export function validateSriLankanPhone(phone) {
// Remove spaces, dashes, and plus signs
const cleaned = phone.replace(/[\s\-\+]/g, '');
// Check if it's a valid Sri Lankan number
const sriLankanPattern = /^(?:94|0)?[1-9][0-9]{8}$/;
if (!sriLankanPattern.test(cleaned)) {
return { isValid: false, formatted: null };
}
// Format to international format
let formatted = cleaned;
if (formatted.startsWith('0')) {
formatted = '94' + formatted.substring(1);
} else if (!formatted.startsWith('94')) {
formatted = '94' + formatted;
}
return { isValid: true, formatted };
}
Message Templates #
export const textLKTemplates = {
welcome: (name) => `Welcome to our service, ${name}! Thanks for joining us.`,
otp: (code) => `Your verification code is: ${code}. Valid for 5 minutes.`,
orderConfirmation: (orderNumber) =>
`Order #${orderNumber} confirmed! We'll notify you when it ships.`,
reminder: (event, time) =>
`Reminder: ${event} is scheduled for ${time}.`,
};
Error Handling #
Comprehensive Error Handler #
export function handleTextLKError(error) {
console.error('Text.LK Error:', error);
// Common error scenarios
if (error.message.includes('401')) {
return 'Invalid API token. Please check your credentials.';
}
if (error.message.includes('400')) {
return 'Invalid phone number or message format.';
}
if (error.message.includes('429')) {
return 'Rate limit exceeded. Please try again later.';
}
return 'Failed to send SMS. Please try again.';
}
Best Practices #
- Security: Never expose your API token in client-side code
- Validation: Always validate phone numbers before sending
- Rate Limiting: Implement client-side rate limiting for user actions
- Error Handling: Provide meaningful error messages to users
- Loading States: Show loading indicators during SMS sending
- Environment Variables: Use different tokens for development and production
Support #
For additional support:
- Visit Text.LK Documentation
- Contact support at [email protected]
- Check API status at status.text.lk
This integration guide is designed to get you sending SMS messages with Text.LK in minutes. Happy coding!