Multilingual

Linsei languages

The Linsei panel speaks 8 languages, and adding yours is just a text file. Here are the available ones and how to create a new translation.

Available languages

The admin panel ships translated into these 8 languages. You can enable or disable them from Settings.

Español
English
Français
Português
Deutsch
Italiano
Nederlands
Polski

Adding a language is this easy

  1. Copy the base file below (en.php).
  2. Translate only the right side of each line. Leave the keys and the placeholders like {v} or {n} exactly as they are.
  3. Save it with your language code, for example it.php or tr.php.
  4. Upload it from the panel under Settings → Languages, or by FTP to data/lang/. It appears instantly.

Base file to copy

This is the English version (en.php). Copy the whole thing and translate the values. If you prefer to start from another language, switch this site's language at the top right.

en.php
<?php if(!defined("PL_APP")){http_response_code(403);exit;}
return [
    'update.title' => 'Update Linsei', 'update.installed' => 'Installed version', 'update.latest' => 'Latest available', 'update.available' => 'Update available!', 'update.uptodate' => 'up to date', 'update.check' => 'Check for updates', 'update.apply' => 'Update to the latest version', 'update.applying' => 'Updating', 'update.confirm' => 'Update the Linsei core now? An automatic backup is made first.', 'update.done' => 'Linsei updated to version {v}.', 'update.err' => 'Could not update', 'update.note' => 'Downloads the core from linsei.com and replaces it without touching your add-ons, your data or your settings. A backup is made first (in data/update/).',
    'form.dup_warn' => 'You already have a link to this same destination: {slug}.', 'form.dup_view' => 'View the existing link', 'form.dup_create_anyway' => 'Create another anyway',
    'nav.settings' => 'Settings', 'settings.title' => 'Settings', 'settings.profile' => 'Your profile', 'settings.my_email' => 'Your email', 'settings.my_email_hint' => 'To receive notices and recover your password.', 'settings.smtp' => 'Mail server (SMTP)', 'settings.smtp_intro' => 'Needed to send password-recovery emails (to you and your managers).', 'settings.smtp_host' => 'Host', 'settings.smtp_port' => 'Port', 'settings.smtp_secure' => 'Security', 'settings.secure_none' => 'No encryption', 'settings.smtp_user' => 'Username', 'settings.smtp_pass' => 'Password', 'settings.pass_set' => 'Saved (leave empty to keep it)', 'settings.mail_from' => 'From address', 'settings.smtp_note' => 'Ask your email or hosting provider for these. They are stored on your server.', 'settings.save' => 'Save settings', 'settings.test_title' => 'Test email', 'settings.test_intro' => 'Send a test email to your address to check SMTP. Save the settings first.', 'settings.test_btn' => 'Send test email', 'settings.test_ok' => 'Test email sent. Check your inbox (and spam folder).', 'settings.test_err' => 'Could not send. Check the SMTP details and that your email is set above.', 'settings.test_subject' => 'Linsei test', 'settings.test_body' => 'If you receive this email, Linsei email sending works correctly.',
    'settings.langs' => 'Languages',
    'settings.langs_intro' => 'Enable or disable the panel languages; disabled ones don\'t show in the switcher. At least one must stay on.',
    'settings.langs_add' => 'Add a language (translated .php file)',
    'settings.langs_add_hint' => 'Upload a file like it.php (a translated copy of es.php). You can also drop it by FTP in data/lang/.',
    'settings.langs_save' => 'Save languages',
    'settings.langs_uploaded' => 'uploaded',
    'settings.lang_added' => 'Language added and enabled.',
    'settings.lang_badfile' => 'Invalid file: it must be a .php returning an array, named with a 2-3 letter code (e.g. it.php).',
    'gest.email' => 'Email', 'gest.email_hint' => 'So they can recover their own password.', 'gest.no_email' => 'no email', 'gest.act_password' => 'Change password', 'gest.act_email' => 'Change recovery email', 'gest.set_password_prompt' => 'New password for this manager (at least 6 characters):', 'gest.set_email_prompt' => 'Manager email (leave empty to remove):', 'gest.flash_pass' => 'Password updated.', 'gest.flash_email' => 'Email updated.', 'gest.err_email' => 'Invalid email.',
    'stats.unique' => 'Unique clicks', 'stats.last_click' => 'Last click', 'stats.peak_day' => 'Peak day', 'stats.avg_day' => 'Avg/day', 'stats.by_os' => 'By OS', 'stats.by_source' => 'Traffic sources', 'stats.by_hour' => 'By hour of day', 'stats.by_weekday' => 'By weekday', 'stats.complement_activity' => 'Add-on activity', 'stats.col_source' => 'Source', 'stats.direct' => 'Direct', 'stats.dow_mon' => 'Mon', 'stats.dow_tue' => 'Tue', 'stats.dow_wed' => 'Wed', 'stats.dow_thu' => 'Thu', 'stats.dow_fri' => 'Fri', 'stats.dow_sat' => 'Sat', 'stats.dow_sun' => 'Sun',
    'dash.geo_update' => 'Update database',
    'help.geo.download' => 'Download the database automatically', 'help.geo.downloading' => 'Downloading', 'help.geo.dl_ok' => 'Geolocation database installed. Visitor countries are now detected (on new clicks).', 'help.geo.dl_err' => 'Could not download or install. Check the server has internet access, or upload the CSV manually.',
    'form.section_link' => 'Link details',
    'form.addons_section' => 'Add-ons',
    'dash.complement_activity' => 'Add-on activity', 'ev.block' => 'Blocked', 'ev.redirect' => 'Redirected',
    'comp.title' => 'Add-ons',
    'comp.intro' => 'Extend Linsei with add-ons. Install or uninstall them in one click; new ones appear automatically.',
    'comp.installed' => 'Installed',
    'comp.install' => 'Install',
    'comp.uninstall' => 'Uninstall',
    'comp.details' => 'More details',
    'comp.version' => 'Version',
    'comp.confirm_uninstall' => 'Uninstall this add-on? It will be deleted from the server.',
    'comp.empty' => 'No add-ons available right now.',
    'comp.ok_install' => 'Add-on installed.',
    'comp.ok_uninstall' => 'Add-on uninstalled.',
    'comp.err_unknown' => 'Unknown add-on.',
    'comp.err_nozip' => 'Your server lacks ZipArchive; upload the add-on via FTP to plugins/.',
    'comp.err_notwritable' => 'The plugins/ folder is not writable.',
    'comp.err_download' => 'Could not download the add-on. Is linsei.com available?',
    'comp.err_badzip' => 'The add-on package is invalid.',
    'comp.upload' => 'Upload add-on',
    'comp.upload_help' => 'Upload a .zip with your add-on (a folder containing its plugin.php). Only you can install it; it runs code on your server, so only upload add-ons you trust.',
    'comp.upload_btn' => 'Upload & install',
    'comp.ok_uploaded' => 'Add-on uploaded and installed.',
    'comp.ok_updated' => 'Add-on updated.',
    'comp.err_nofile' => 'Choose a .zip file to upload.',
    'comp.err_invalid' => 'The .zip does not look like a valid add-on (it must contain a plugin.php).',
    'comp.err_toobig' => 'The file is too large (max 8 MB).',
    'login.forgot' => 'Forgot your password?',
    'recover.title' => 'Recover password',
    'recover.intro' => 'Enter your account email and we\'ll send you a link to set a new password.',
    'recover.email' => 'Email',
    'recover.send' => 'Send link',
    'recover.sent' => 'If that email exists, we\'ve sent you a link to reset your password. Check your inbox.',
    'recover.back' => 'Back to login',
    'recover.mail_subject' => 'Reset your Linsei password',
    'recover.mail_body' => 'You requested a password reset. Open this link (expires in 1 hour):',
    'reset.title' => 'New password',
    'reset.intro' => 'Enter your new password (at least 6 characters).',
    'reset.password' => 'New password',
    'reset.save' => 'Save password',
    'reset.bad' => 'The link is invalid or has expired. Request a new one.',
    'reset.done' => 'Password changed. You can now log in.',
    'reset.go_login' => 'Go to login',
    'inst.admin_email' => 'Administrator email',
    'inst.admin_email_hint' => 'We\'ll use it to recover your password if you forget it.',
    'inst.err_email' => 'Enter a valid email.',
    'help.email.title' => 'Your email',
    'help.email.body' => 'Needed to recover your password if you forget it.',
    'help.email.save' => 'Save email',

    'nav.dashboard' => 'Dashboard',
    'nav.links' => 'Links',
    'nav.gestores' => 'Managers',
    'nav.help' => 'Help',
    'nav.complementos' => 'Add-ons',
    'nav.logout' => 'Log out',

    'common.new_link' => 'New link',
    'common.back' => 'Back',
    'common.cancel' => 'Cancel',
    'common.view' => 'View',
    'common.clicks' => 'Clicks',
    'common.optional' => '(optional)',
    'common.actions' => 'Actions',
    'common.export_csv' => 'Export CSV',

    'login.subtitle' => 'Admin panel',
    'login.user' => 'Username',
    'login.password' => 'Password',
    'login.enter' => 'Sign in',
    'login.error_bad' => 'Incorrect username or password.',

    'dash.title' => 'Dashboard',
    'dash.subtitle_admin' => 'Global view (administrator)',
    'dash.subtitle_user' => 'Summary of your links',
    'dash.kpi_links' => 'Links',
    'dash.kpi_total_clicks' => 'Total clicks',
    'dash.kpi_today' => 'Clicks today',
    'dash.kpi_active' => 'Active links',
    'dash.evolution' => 'Click trend (last 30 days)',
    'dash.by_country' => 'By country',
    'dash.by_device' => 'By device',
    'dash.by_browser' => 'By browser',
    'dash.top_links' => 'Best performing links',
    'dash.no_links' => 'No links yet.',
    'dash.create_first' => 'Create the first one',
    'dash.col_link' => 'Link',
    'dash.manager_perf' => 'Performance by manager',
    'dash.no_managers' => 'No managers yet.',
    'dash.create_manager' => 'Create a manager',
    'dash.col_manager' => 'Manager',

    'links.title' => 'Links',
    'links.col_short' => 'Short link',
    'links.col_dest' => 'Destination',
    'links.col_status' => 'Status',
    'links.none' => 'No links yet.',
    'links.flash_created' => 'Link created successfully.',
    'links.flash_updated' => 'Link updated.',
    'links.flash_deleted' => 'Link deleted.',
    'links.confirm_delete' => 'Delete this link and its statistics?',
    'links.search_ph' => 'Search by slug, destination or title…',
    'links.total' => '{n} links in total',
    'links.filtered_by' => 'Links by {user}',
    'links.clear_filter' => 'Clear filter',
    'links.col_created' => 'Created',
    'links.per_page' => 'Per page',
    'links.first' => 'First',
    'links.last' => 'Last',
    'links.bulk_export' => 'Export selection',
    'links.bulk_delete' => 'Delete selection',
    'links.bulk_activate' => 'Activate',
    'links.bulk_deactivate' => 'Deactivate',
    'links.bulk_clear' => 'Clear selection',
    'links.bulk_selected' => 'selected',
    'links.bulk_confirm_delete' => 'Delete the selected links? This cannot be undone.',
    'links.flash_bulk_deleted' => 'Links deleted.',
    'links.flash_bulk_activated' => 'Links activated.',
    'links.flash_bulk_deactivated' => 'Links deactivated.',
    'links.page_of' => 'Page {page} of {pages}',
    'links.no_results' => 'No links match your search.',
    'common.prev' => 'Previous',
    'common.next' => 'Next',
    'status.active' => 'Active',
    'status.inactive' => 'Inactive',
    'status.expired' => 'Expired',
    'status.limit' => 'Limit',

    'form.new_title' => 'New link',
    'form.edit_title' => 'Edit link',
    'form.target' => 'Destination URL',
    'form.target_hint' => 'If you omit http(s):// then https:// is added automatically.',
    'form.short_label' => 'Short link',
    'form.slug_fixed_hint' => 'The slug cannot be changed when editing, so already shared links keep working.',
    'form.prefix' => 'Prefix',
    'form.custom_slug' => 'Custom slug',
    'form.slug_result_hint' => 'Leave it empty to generate a random code. If the slug already exists, that link is updated.',
    'form.title_prefix' => 'Title prefix',
    'form.title' => 'Title',
    'form.expires' => 'Expires on',
    'form.max_clicks' => 'Max clicks',
    'form.no_limit' => 'No limit',
    'form.active' => 'Link active',
    'form.btn_create' => 'Create link',
    'form.btn_save' => 'Save changes',
    'form.utm_toggle' => 'Add UTM parameters',
    'form.utm_hint' => 'Added to the target URL to track your campaigns in analytics (Google Analytics, etc.).',
    'form.err_url' => 'Enter a valid destination URL.',
    'form.err_slug' => 'That slug is not allowed, choose another one.',
    'form.err_slug_taken' => 'The slug "{slug}" is already in use by another manager.',

    'stats.title' => 'Link statistics',
    'stats.short' => 'Short link',
    'stats.dest' => 'Destination',
    'stats.total' => 'Total clicks',
    'stats.manager' => 'Manager',
    'stats.evolution' => 'Trend (last 30 days)',
    'stats.recent' => 'Recent clicks',
    'stats.col_date' => 'Date',
    'stats.col_country' => 'Country',
    'stats.col_device' => 'Device',
    'stats.col_browser' => 'Browser',
    'stats.col_os' => 'OS',
    'stats.none' => 'No clicks yet.',

    'gest.title' => 'URL managers',
    'gest.del_title' => 'Delete manager',
    'gest.del_intro' => 'You are about to delete the manager {user}.',
    'gest.del_has' => 'They have {n} links. What do you want to do with them?',
    'gest.del_reassign' => 'Reassign their links to another manager',
    'gest.del_reassign_hint' => 'Links and their stats are kept; they move to the manager you pick.',
    'gest.del_delete_all' => 'Also delete their links and stats',
    'gest.del_delete_hint' => 'Their short URLs will stop working. This is irreversible.',
    'gest.del_nolinks' => 'This manager has no links. Only the account will be removed.',
    'gest.del_choose' => '- pick a manager -',
    'gest.del_submit' => 'Delete manager',
    'gest.del_cancel' => 'Cancel',
    'gest.err_target' => 'Pick a valid manager to reassign the links to.',
    'gest.act_delete' => 'Delete manager',
    'gest.act_enable' => 'Enable manager',
    'gest.act_disable' => 'Disable manager',
    'gest.view_links' => 'View all their links',
    'gest.period' => 'Period',
    'gest.p_month' => 'This month',
    'gest.p_lastmonth' => 'Last month',
    'gest.p_last30' => 'Last 30 days',
    'gest.p_year' => 'This year',
    'gest.p_all' => 'All',
    'gest.from' => 'From',
    'gest.to' => 'To',
    'gest.apply' => 'Apply',
    'gest.col_links' => 'Links created',
    'gest.admin_badge' => 'Admin',
    'gest.period_hint' => 'Links created and clicks received in the selected period.',
    'gest.registered' => 'Registered managers',
    'gest.none' => 'No managers yet. Create the first one with the form.',
    'gest.col_top' => 'Top',
    'gest.new' => 'New manager',
    'gest.user' => 'Username',
    'gest.name' => 'Name',
    'gest.password' => 'Password',
    'gest.create' => 'Create manager',
    'gest.flash_created' => 'Manager created successfully.',
    'gest.flash_deleted' => 'Manager deleted.',
    'gest.confirm_delete' => 'Delete this manager? All their links and stats will also be removed, and their URLs will stop working. This cannot be undone.',
    'gest.err_user' => 'The username must be at least 3 lowercase characters (letters, numbers, . _ -).',
    'gest.err_pass' => 'The password must be at least 6 characters.',
    'gest.err_exists' => 'That username already exists.',

    'err.back_panel' => 'Back to panel',
    'err.notfound_title' => 'Link not found',
    'err.notfound_msg' => 'This link does not exist or has been disabled.',
    'err.denied_title' => 'Access denied',
    'err.denied_msg' => 'You do not have permission to access this section.',
    'err.expired_title' => 'Link expired',
    'err.expired_msg' => 'This link has expired and is no longer available.',
    'err.limit_title' => 'Limit reached',
    'err.limit_msg' => 'This link reached its maximum number of visits.',
    'err.404_title' => 'Not found',
    'err.404_msg' => 'The page you are looking for does not exist.',
    'err.csrf_title' => 'Session expired',
    'err.csrf_msg' => 'The security token is invalid. Reload the page and try again.',
    'err.link_notfound' => 'Link not found.',
    'err.link_denied' => 'You do not have permission over this link.',

    'help.title' => 'Help & documentation',
    'help.intro' => 'A quick guide to get the most out of Linsei. If in doubt, here is how each part works.',
    'help.create.title' => 'Create and customize links',
    'help.create.body' => 'From Links, click "New link". Enter the destination URL and, optionally, a prefix and a custom slug to form an address like yourdomain.com/blog-my-link. Leave the slug empty to generate a random code. If you create a link with a slug that already exists (and is yours), it is updated instead of duplicated.',
    'help.titles.title' => 'Title prefix',
    'help.titles.body' => 'You can prepend a prefix to your link titles to organize them by campaign or section, which makes analysis easier.',
    'help.expire.title' => 'Expiration and click limit',
    'help.expire.body' => 'Each link can expire on a specific date or after a maximum number of visits. Once exceeded, the link stops redirecting.',
    'help.stats.title' => 'Statistics',
    'help.stats.body' => 'The dashboard shows total clicks, today\'s clicks and their trend, plus a breakdown by country, device and browser. Each link has its own statistics page and you can export everything to CSV.',
    'help.roles.title' => 'Roles: administrator and manager',
    'help.roles.body' => 'The administrator sees and manages everything. Each manager only sees and manages their own links and statistics. Managers are created from the Managers section.',
    'help.lang.title' => 'Language',
    'help.lang.body' => 'Use the language selector in the top bar to switch between Spanish, English, French and Portuguese. Your choice is remembered for the session.',
    'help.api.title' => 'API and Chrome extension',
    'help.api.body' => 'Each user has an API token to create links from outside the panel, for example with the Chrome extension that shortens the current tab URL with one click.',
    'help.ext_guide' => 'Download and install the Chrome extension',
    'help.geo.title' => 'Geolocation by country',
    'help.geo.active' => 'Active: {n} ranges loaded.',
    'help.geo.inactive' => 'Not configured: the click country is saved as “Unknown”.',
    'help.geo.body' => 'To show visitor country without relying on your host, download a free IP→country CSV database (columns: ip_start, ip_end, country) (e.g. IP2Location LITE DB1, or the CSVs from github.com/sapics/ip-location-db) and upload it as data/geoip.csv. Linsei builds the index automatically. No IP leaves your server.',

    'inst.subtitle' => 'Installation wizard',
    'inst.req_title' => 'Server requirements',
    'inst.continue' => 'Continue',
    'inst.req_php' => 'PHP 7.4 or higher (you have {version})',
    'inst.req_pdo' => 'PDO extension',
    'inst.req_driver' => 'MySQL or SQLite driver',
    'inst.req_writable' => 'Project folder writable',
    'inst.req_data' => 'data/ folder writable',
    'inst.req_php_hint' => 'Change the PHP version in your hosting panel.',
    'inst.req_pdo_hint' => 'Enable the PDO extension in your hosting.',
    'inst.req_driver_hint' => 'You need pdo_mysql (recommended) or pdo_sqlite.',
    'inst.req_writable_hint' => 'Otherwise you can create config.php manually at the end.',
    'inst.req_data_hint' => 'Required for the SQLite option. Give it write permissions.',
    'inst.db_title' => 'Database',
    'inst.db_mysql' => 'MySQL / MariaDB',
    'inst.db_mysql_note' => '(recommended on hosting)',
    'inst.db_sqlite' => 'SQLite',
    'inst.db_sqlite_note' => '(no configuration, ideal for local testing)',
    'inst.db_server' => 'Host',
    'inst.db_port' => 'Port',
    'inst.db_name' => 'Database name',
    'inst.db_user' => 'User',
    'inst.db_password' => 'Password',
    'inst.db_submit' => 'Test connection and continue',
    'inst.admin_title' => 'Administrator account',
    'inst.site_url' => 'Site URL',
    'inst.site_url_hint' => 'Public address where Linsei lives, without a trailing slash.',
    'inst.admin_user' => 'Administrator username',
    'inst.admin_name' => 'Name',
    'inst.admin_password' => 'Password',
    'inst.install_btn' => 'Install Linsei',
    'inst.done_title' => 'Installation complete',
    'inst.done_msg' => 'Linsei is ready. Sign in to the panel with the administrator account you just created.',
    'inst.done_security' => 'Security tip: if your hosting allows it, remove write permission from config.php once installed.',
    'inst.done_go' => 'Go to panel',
    'inst.manual_title' => 'Create config.php manually',
    'inst.manual_msg' => 'config.php could not be written automatically because the folder is not writable. Create a file named config.php in the project root with this content and then click the button:',
    'inst.manual_btn' => 'I created config.php, go to panel',
    'inst.err_conn' => 'Could not connect: {error}',
    'inst.err_user' => 'The username must be at least 3 lowercase characters (letters, numbers, . _ -).',
    'inst.err_pass' => 'The password must be at least 6 characters.',
    'inst.err_db' => 'Error preparing the database: {error}',
    // --- Statistics section ---
    'nav.stats' => 'Statistics',
    'st.title' => 'Statistics', 'st.sub_admin' => 'Global analytics across all links', 'st.sub_user' => 'Analytics for your links',
    'st.r_today' => 'Today', 'st.r_7d' => '7 days', 'st.r_30d' => '30 days', 'st.r_90d' => '3 months', 'st.r_12m' => '12 months', 'st.r_all' => 'All',
    'st.from' => 'From', 'st.to' => 'To', 'st.apply' => 'Apply',
    'st.showing' => '{from} to {to}', 'st.vs_prev' => 'compared with {from} - {to}',
    'st.kpi_clicks' => 'Clicks in period', 'st.kpi_unique' => 'Unique visitors', 'st.kpi_newlinks' => 'Links created',
    'st.new' => 'New', 'st.vs' => 'vs. previous',
    'st.evolution' => 'Clicks over time', 'st.by_day' => 'by day', 'st.by_month' => 'by month',
    'st.this_period' => 'Current period', 'st.prev_period' => 'Previous period',
    'st.by_os' => 'By OS', 'st.top_period' => 'Most-clicked links in period', 'st.no_data' => 'No clicks in this period.',
    'st.by_manager' => 'By manager', 'st.col_newlinks' => 'New links', 'st.col_created' => 'Created',
];

Translated Linsei into your language? Share it with the community.