Getting Started
- Install with Composer:
composer require webmil/text-language-detect.
- Before writing integration code, inspect the package itself:
vendor/webmil/text-language-detect/README.md
vendor/webmil/text-language-detect/composer.json for PHP/Laravel constraints
vendor/webmil/text-language-detect/src/ for the detector class, service provider, facade, config, and return types
- any
tests/ directory for expected behavior and sample languages
- Because the repository metadata is unavailable, confirm the exact namespace, class name, provider, facade, and whether
detect() returns a string or a scored array. Treat the README as the source of truth.
- If the package ships a Laravel service provider, check whether auto-discovery registers it. On older Laravel versions, add the provider/facade to
config/app.php manually.
- First use case: detect the language of a contact form, support ticket, or profile bio, persist an ISO language code, and fall back to the app locale when confidence is low.
Typical first integration, adjusted to the package’s real class/method names:
use Webmil\TextLanguageDetect\TextLanguageDetect;
$detector = app(TextLanguageDetect::class); // or new TextLanguageDetect()
$text = $request->string('body')->toString();
$result = $detector->detect($text); // inspect shape: string or language => score array
$language = is_array($result)
? array_key_first($result)
: $result;
If the package exposes a simple detector method such as detectSimple(), prefer it when you only need one language code.
Implementation Patterns
- Wrap the package behind your own service or interface. Keep vendor calls out of controllers, models, and Blade views.
- Use it as a heuristic, not a source of truth. Store the detected language alongside a confidence score or a “manual override” field when the result affects user experience.
- Normalize input before detection:
- strip HTML tags, URLs, email addresses, mentions, and excessive whitespace
- ensure UTF-8
- enforce a minimum text length
- Use confidence thresholds. For example, accept the top language only when its score exceeds a configured threshold; otherwise return
null and fall back to the user’s locale.
- Cache results by a hash of the normalized text. Language detection is deterministic enough for caching and can be expensive on large batches.
- For bulk content, queue detection jobs or chunk large documents rather than calling the detector once per row inside a web request.
- Add a config file or app-level config for:
- supported language codes
- minimum text length
- confidence threshold
- fallback locale
- whether to store raw scores
- Map the package’s language codes to your application’s locale format. The package may return ISO 639-1, ISO 639-2, or names depending on configuration; normalize once in your wrapper.
- Add tests with representative fixtures: short text, long text, mixed-language text, HTML-heavy text, emojis, and unsupported languages.
Example wrapper:
final class LanguageDetector
{
public function __construct(
private TextLanguageDetect $detector,
private array $config
) {}
public function detect(string $text): ?string
{
$text = trim(strip_tags($text));
if (mb_strlen($text) < $this->config['min_length']) {
return null;
}
$result = $this->detector->detect($text);
if (is_string($result)) {
return $this->mapLanguage($result);
}
arsort($result);
$code = array_key_first($result);
$score = $result[$code] ?? 0;
return $score >= $this->config['threshold']
? $this->mapLanguage($code)
: null;
}
private function mapLanguage(string $code): ?string
{
return in_array($code, $this->config['supported'], true)
? $code
: null;
}
}
Use cases where this package fits well:
- auto-tagging support tickets or contact requests
- suggesting a translation locale
- analytics grouping by content language
- content moderation triage
- routing messages to language-specific queues or teams
Avoid using it as a security control, legal compliance mechanism, or the only signal for high-stakes localization.
Gotchas and Tips
- Short text is unreliable. “OK”, “Hi”, names, product codes, and URLs often produce false positives. Require a minimum length or fall back to locale.
- Mixed-language text and code-switching are hard. A single detected language can be misleading; consider storing the top scores or asking the user to confirm.
- Normalize aggressively before detection. HTML, markdown, URLs, mentions, and boilerplate can dominate the result.
- Inspect the raw return value first. The package may return a string, an array of language codes, or an array of scores. Build your wrapper around the actual shape, not the assumed one.
- Confidence scores are package-specific. Do not assume
0.8 means the same thing as in another detector. Calibrate thresholds against your own sample data.
- Language codes differ between packages and Laravel locales. For example,
en, eng, and English may all appear depending on configuration. Normalize in one place.
- Check Composer constraints early. Older packages may not support your PHP or Laravel version, may not use auto-discovery, or may require manual provider registration.
- If the package has config, remember
php artisan config:cache after changes in production.
- Instantiate or resolve the detector once per request/job where possible. Avoid constructing it repeatedly in loops.
- Log the normalized input hash, raw result, chosen language, and confidence during rollout. This makes false positives debuggable without storing sensitive text.
- Always provide a fallback and a user override. Language detection should degrade gracefully.
- Wrap the vendor class in an interface so you can swap in another detector or a custom implementation later.
- At 44 stars and a low assessment score, treat this as a small utility dependency. Pin the version, review upgrades, and avoid making it a critical-path dependency without tests and a fallback strategy.