Automated summary
A guide for adding Urdu localization to a Next.js app: next-intl setup, English/Urdu JSON translation files, RTL support and a language switcher.
Strengths
- Concrete, copy-pasteable next-intl setup (next.config.ts plugin, i18n.ts, locale-detection middleware)
- Matching en/ur key sets for common, auth, tasks, chat and settings that can be reused directly
- Explicit checklist of remaining work: Tailwind RTL layout, Urdu AI agent responses, language switcher UI
- Narrow allowed-tools list (Bash, Write, Read, Glob, Edit, Grep) that bounds what the agent can touch
Limitations
- The file is truncated: the Urdu priority translations cut off mid-entry, and the RTL, AI-agent and switcher sections are only named, never detailed
- Tightly bound to one hackathon project ("Evolution Todo", frontend/ paths, Phase 5 constitution), so it needs rework elsewhere
- No guidance on plurals, number/date formatting, native-speaker review, or testing RTL rendering
Use it when adding an English/Urdu bilingual, RTL-capable interface to a Next.js app built on next-intl.
Skip it for non-Next.js stacks or when you need production-grade localization with plurals, formatting and native review.
Security analysis
SafeThe skill provides legitimate i18n/RTL setup instructions and code snippets for adding Urdu support. It uses Bash only for ordinary npm installs and contains no destructive, exfiltration, obfuscation, or safety-disabling behavior.
No concerns found
How this analysis is madeExamples
Set up next-intl in our Next.js frontend with 'en' and 'ur' locales, add the middleware for locale detection, and create en.json and ur.json translation files for the task screens.Configure Tailwind RTL support so the whole app flips direction when the user switches to Urdu, including the sidebar, forms and task cards.Make the AI assistant reply in Urdu when the app language is set to Urdu, and add a language switcher in the settings page.name: urdu-language-support description: Implement Urdu language support with RTL layout, translations, and AI responses in Urdu. Bonus feature (+100 points) for Phase 5. (project) allowed-tools: Bash, Write, Read, Glob, Edit, Grep
Urdu Language Support Skill
Quick Start
- Read Phase 5 Constitution -
constitution-prompt-phase-5.md - Set up i18n - next-intl or react-intl
- Create Urdu translations - JSON translation files
- Configure RTL support - Tailwind RTL plugin
- Update AI agent - Urdu response capability
- Add language switcher - UI component
Bonus Points: +100
This is a bonus feature for Phase 5 that adds 100 points to the hackathon score.
i18n Setup with next-intl
Installation
cd frontend
npm install next-intl
Next.js Configuration
// frontend/next.config.ts
import createNextIntlPlugin from 'next-intl/plugin';
const withNextIntl = createNextIntlPlugin();
const nextConfig = {
// ... other config
};
export default withNextIntl(nextConfig);
i18n Configuration
// frontend/i18n.ts
import { getRequestConfig } from 'next-intl/server';
export default getRequestConfig(async ({ locale }) => ({
messages: (await import(`./messages/${locale}.json`)).default
}));
Middleware for Locale Detection
// frontend/middleware.ts
import createMiddleware from 'next-intl/middleware';
export default createMiddleware({
locales: ['en', 'ur'],
defaultLocale: 'en',
localePrefix: 'as-needed'
});
export const config = {
matcher: ['/((?!api|_next|.*\\..*).*)']
};
Translation Files
English Translations
// frontend/messages/en.json
{
"common": {
"appName": "Evolution Todo",
"loading": "Loading...",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"edit": "Edit",
"search": "Search",
"filter": "Filter",
"sort": "Sort"
},
"auth": {
"login": "Login",
"signup": "Sign Up",
"logout": "Logout",
"email": "Email",
"password": "Password",
"forgotPassword": "Forgot Password?"
},
"tasks": {
"title": "Tasks",
"newTask": "New Task",
"addTask": "Add Task",
"editTask": "Edit Task",
"deleteTask": "Delete Task",
"taskTitle": "Task Title",
"description": "Description",
"priority": "Priority",
"dueDate": "Due Date",
"status": "Status",
"tags": "Tags",
"reminder": "Reminder",
"priorities": {
"low": "Low",
"medium": "Medium",
"high": "High"
},
"statuses": {
"pending": "Pending",
"inProgress": "In Progress",
"completed": "Completed"
},
"noTasks": "No tasks found",
"completedTasks": "Completed Tasks"
},
"chat": {
"title": "AI Assistant",
"placeholder": "Ask me anything about your tasks...",
"send": "Send",
"thinking": "Thinking...",
"newConversation": "New Conversation"
},
"settings": {
"title": "Settings",
"language": "Language",
"theme": "Theme",
"notifications": "Notifications"
}
}
Urdu Translations
// frontend/messages/ur.json
{
"common": {
"appName": "ایوولیوشن ٹوڈو",
"loading": "لوڈ ہو رہا ہے...",
"save": "محفوظ کریں",
"cancel": "منسوخ کریں",
"delete": "حذف کریں",
"edit": "ترمیم کریں",
"search": "تلاش کریں",
"filter": "فلٹر",
"sort": "ترتیب دیں"
},
"auth": {
"login": "لاگ ان",
"signup": "سائن اپ",
"logout": "لاگ آؤٹ",
"email": "ای میل",
"password": "پاس ورڈ",
"forgotPassword": "پاس ورڈ بھول گئے؟"
},
"tasks": {
"title": "کام",
"newTask": "نیا کام",
"addTask": "کام شامل کریں",
"editTask": "کام میں ترمیم کریں",
"deleteTask": "کام حذف کریں",
"taskTitle": "کام کا عنوان",
"description": "تفصیل",
"priority": "ترجیح",
"dueDate": "آخری تاریخ",
"status": "حیثیت",
"tags": "ٹیگز",
"reminder": "یاد دہانی",
"priorities": {
"low": "کم",
"medium": "درمیانی",
"high": "زیادہ"
},
"statuses": {
"pending": "زیر التواء",
"inProgress": "جاری",
"completed": "مکمل"
},
"noTasks": "کوئی کام نہیں ملا",
"completedTasks": "مکمل شدہ کام"
},
"chat": {
"title": "AI معاون",
"placeholder": "اپنے کاموں کے بارے میں کچھ بھی پوچھیں...",
"send": "بھیجیں",
"thinking": "سوچ رہا ہوں...",
"newConversation": "نئی گفتگو"
},
"settings": {
"title": "ترتیبات",
"language": "زبان",
"theme": "تھیم",
"notifications": "اطلاعات"
}
}
RTL Support with Tailwind
Tailwind RTL Plugin
npm install tailwindcss-rtl
Tailwind Configuration
// frontend/tailwind.config.ts
import type { Config } from "tailwindcss";
import rtl from "tailwindcss-rtl";
const config: Config = {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [rtl],
};
export default config;
RTL Layout Component
// frontend/components/layout/rtl-provider.tsx
"use client";
import { useLocale } from "next-intl";
import { useEffect } from "react";
export function RTLProvider({ children }: { children: React.ReactNode }) {
const locale = useLocale();
const isRTL = locale === "ur";
useEffect(() => {
document.documentElement.dir = isRTL ? "rtl" : "ltr";
document.documentElement.lang = locale;
}, [locale, isRTL]);
return <>{children}</>;
}
RTL-Aware Components
// frontend/components/ui/rtl-text.tsx
import { cn } from "@/lib/utils";
import { useLocale } from "next-intl";
interface RTLTextProps {
children: React.ReactNode;
className?: string;
}
export function RTLText({ children, className }: RTLTextProps) {
const locale = useLocale();
const isRTL = locale === "ur";
return (
<span className={cn(
isRTL && "font-urdu", // Custom Urdu font
className
)}>
{children}
</span>
);
}
Language Switcher Component
// frontend/components/language-switcher.tsx
"use client";
import { useLocale, useTranslations } from "next-intl";
import { useRouter, usePathname } from "next/navigation";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Globe } from "lucide-react";
const languages = [
{ code: "en", name: "English", nativeName: "English" },
{ code: "ur", name: "Urdu", nativeName: "اردو" },
];
export function LanguageSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
const t = useTranslations("settings");
const handleChange = (newLocale: string) => {
// Remove current locale prefix and add new one
const newPath = pathname.replace(`/${locale}`, `/${newLocale}`);
router.push(newPath);
};
return (
<Select value={locale} onValueChange={handleChange}>
<SelectTrigger className="w-[140px]">
<Globe className="h-4 w-4 me-2" />
<SelectValue />
</SelectTrigger>
<SelectContent>
{languages.map((lang) => (
<SelectItem key={lang.code} value={lang.code}>
{lang.nativeName}
</SelectItem>
))}
</SelectContent>
</Select>
);
}
AI Agent Urdu Support
Update Agent Prompt
# backend/src/agents/prompts.py
SYSTEM_PROMPT_URDU = """
آپ ایک مددگار AI اسسٹنٹ ہیں جو صارفین کو ان کے کاموں کا انتظام کرنے میں مدد کرتا ہے۔
آپ یہ کر سکتے ہیں:
- نئے کام بنائیں
- کاموں کی فہرست دیکھیں
- کام مکمل کریں
- کام حذف کریں
- کاموں میں ترمیم کریں
- یاد دہانیاں مقرر کریں
ہمیشہ اردو میں جواب دیں اور شائستہ رہیں۔
"""
def get_system_prompt(language: str = "en") -> str:
"""Get system prompt based on language."""
if language == "ur":
return SYSTEM_PROMPT_URDU
return SYSTEM_PROMPT_EN
Language Detection
# backend/src/agents/language.py
import langdetect
def detect_language(text: str) -> str:
"""Detect language of input text."""
try:
lang = langdetect.detect(text)
return "ur" if lang == "ur" else "en"
except:
return "en"
def should_respond_in_urdu(user_message: str) -> bool:
"""Check if response should be in Urdu."""
return detect_language(user_message) == "ur"
Updated Agent
# backend/src/agents/todo_agent.py
from .language import should_respond_in_urdu, get_system_prompt
async def run_agent(user_message: str, user_id: str):
"""Run AI agent with language support."""
# Detect language
use_urdu = should_respond_in_urdu(user_message)
system_prompt = get_system_prompt("ur" if use_urdu else "en")
# Create agent with appropriate prompt
agent = Agent(
name="todo_assistant",
instructions=system_prompt,
model="gemini/gemini-2.0-flash",
tools=[...],
)
# Run and return response
response = await Runner.run(agent, user_message)
return response
Urdu Font Configuration
Google Fonts Setup
// frontend/app/layout.tsx
import { Noto_Nastaliq_Urdu, Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
const urduFont = Noto_Nastaliq_Urdu({
subsets: ["arabic"],
variable: "--font-urdu",
weight: ["400", "700"],
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body className={`${inter.variable} ${urduFont.variable}`}>
{children}
</body>
</html>
);
}
Tailwind Font Configuration
// frontend/tailwind.config.ts
const config: Config = {
theme: {
extend: {
fontFamily: {
sans: ["var(--font-inter)", "sans-serif"],
urdu: ["var(--font-urdu)", "serif"],
},
},
},
};
Usage in Components
// frontend/components/tasks/task-card.tsx
"use client";
import { useTranslations } from "next-intl";
import { PriorityBadge } from "./priority-badge";
export function TaskCard({ task }: { task: Task }) {
const t = useTranslations("tasks");
return (
<div className="p-4 border rounded-lg">
<h3 className="font-bold">{task.title}</h3>
<p className="text-muted-foreground">{task.description}</p>
<div className="flex items-center gap-2 mt-2">
<span className="text-sm">{t("priority")}:</span>
<PriorityBadge priority={task.priority} />
</div>
<div className="flex items-center gap-2 mt-1">
<span className="text-sm">{t("status")}:</span>
<span>{t(`statuses.${task.status}`)}</span>
</div>
</div>
);
}
Verification Checklist
- [ ] next-intl installed and configured
- [ ] English translations complete
- [ ] Urdu translations complete
- [ ] RTL support working
- [ ] Language switcher component created
- [ ] Urdu font loaded (Noto Nastaliq)
- [ ] AI agent responds in Urdu
- [ ] All UI text is translatable
- [ ] Direction changes correctly on language switch
- [ ] No layout breaks in RTL mode
Troubleshooting
| Issue | Cause | Solution |
|-------|-------|----------|
| Font not loading | Missing import | Add Noto Nastaliq to layout |
| RTL not working | Missing dir attribute | Set in RTLProvider |
| Translation missing | Key not in JSON | Add to messages file |
| AI responds in English | No language detection | Add langdetect check |
| Text overflow | RTL text handling | Use text-start/text-end |
References
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/urdu-language-support-mmlj2oan/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/urdu-language-support-mmlj2oan' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/urdu-language-support-mmlj2oan/download' --output '.skill-downloads/urdu-language-support-mmlj2oan/SKILL.md.part' && mv '.skill-downloads/urdu-language-support-mmlj2oan/SKILL.md.part' '.skill-downloads/urdu-language-support-mmlj2oan/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Tools declared by the author (check availability in your agent): Bash, Write, Read, Glob, Edit, Grep
Original excerpt: Installation
cd frontend
npm install next-intl
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/urdu-language-support-mmlj2oan/SKILL.md' && test -s '.skill-downloads/urdu-language-support-mmlj2oan/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/urdu-language-support' && cp -R '.skill-downloads/urdu-language-support-mmlj2oan' '.claude/skills/urdu-language-support'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/urdu-language-support-mmlj2oan'openskills read 'urdu-language-support-mmlj2oan'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/urdu-language-support-mmlj2oan/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.