Skip to main content
Tutorial

Building a REST API in Laravel That Handles Arabic Text Properly

4 min read

How Laravel's default UTF8 doesn't handle Arabic properly — and what actually works

LaravelArabic textREST APIPHP charsetMySQL UTF8MB4

Last summer, I inherited a Laravel API for a Saudi real estate portal. The client kept getting complaints that Arabic property descriptions looked like a garbled mess in the mobile app. I clicked through their staging environment — sure enough, الْعَرَبِيّة turned into ‫العربية‬. Not exactly the vibe when you're selling villas in Riyadh.

The Database Layer: UTF8 Is a Lie

If you’re using Laravel’s default MySQL configuration, stop right now. The utf8 charset MySQL ships with? It doesn’t actually handle Arabic properly. You need utf8mb4. Took me three projects to learn this. Don’t be me.

In config/database.php, change your charset and collation settings like so:

php
'mysql' => [
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
]

But wait — your database tables won’t update themselves. I had to run raw queries to fix existing data:

sql
ALTER TABLE properties CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Miss this step, and older records will still look broken. Laravel won’t yell at you. The world will just quietly hate you.

PHP Configuration: Blame Your Own Machine

Turns out even perfect Laravel settings can get wrecked by PHP’s mbstring defaults. Found this out after spending 4 hours swearing at my test cases.

Check your php.ini:

ini
mbstring.language = Arabic
mbstring.internal_encoding = UTF-8
mbstring.http_input = UTF-8
mbstring.http_output = UTF-8
mbstring.encoding_translation = 1

If you’re using Laravel Sail or Docker containers, make sure these changes are in both host and container environments. I once chased this bug because docker-compose up was reading an outdated image. Never again.

When It Still Broke For No Reason

The worst part? Even after DB and PHP side worked, my response headers were fighting me. Laravel by default sends Content-Type: text/html for APIs. Which meant some browsers were guessing encodings like it was 2003.

Fixed it by forcing a charset in the response:

php
$response = response()->json($data);
$response->headers->set('Content-Type', 'application/json; charset=UTF-8');
return $response;

Wish there was a centralized way to handle this. Maybe a middleware someday when I’m less lazy.

Real Testing Means Using Arabic Input

You can’t just test with Postman. I used a form from a UAE event management client that sends Arabic names through Tawasul Limo’s booking system. Real POST payloads from actual Android phones revealed issues with normalisation — like how ة gets transformed during validation.

Pro tip: Use \Illuminate\Support\Str::ascii() with extreme caution. It mangles Arabic text by design. We ended up whitelisting Arabic ranges in our input sanitation rules.

php
Validator::make($request->all(), [
    'name' => ['required', 'regex:/^[\p{Arabic}\p{L}\p{N} ]+$/u']
]);

The Human Part

I once spent two days debugging a client’s SMS gateway integration for Reach Home Properties, because the provider had hardcoded cp1256 support. Laravel was doing everything right. Their API was just… bad. Had to force iconv('UTF-8', 'WINDOWS-1256//TRANSLIT//IGNORE', $text) for their endpoint. Still makes my skin crawl.

Wrap Up

If your Laravel API serves Arabic audiences — which it should, given the GCC’s growing app market — these aren’t optional steps. Some clients expect perfect Arabic handling out of the box. They’re not wrong.

Got questions? Found a better way to handle this? Hit me up on sarahprofile.com/contact. I’ll probably steal your idea for the next client in Jeddah.

S

Sarah

Senior Full-Stack Developer & PMP-Certified Project Lead — Abu Dhabi, UAE

7+ years building web applications for UAE & GCC businesses. Specialising in Laravel, Next.js, and Arabic RTL development.

Work with Sarah