Jump to content

How to build a multilingual site in Squarespace 7 - without drawbacks & extra cost

Recommended Posts

There are several approaches to realize a multilingual site in Squarespace.All of the existing solutions have drawbacks. In the answer, you will find a solution for localization of squarespace sites without drawbacks.

1) Official Squarespace Solution

  • Does not work on all templates.
  • Structural limitation - you only have one navigation level left perlanguage.
  • Language selector menu not very nice.

2) Using multiple squarespace sites with language subdomains

  • You have to pay the Squarespace fee per language

3) Using external localization services like localize.js oder bablic.com

  • You have to pay for external services.

  • There are additional resources that have to be downloaded

  • Does SEO work well on these solutions? Did not investigate this.

4) Javascript based on CSS Selectors and page IDs

  • Unflexible when adding pages, JS has to be adapted and grows
Edited by edokken

I am a freelance developer situated in southern germany. I offer full service websites, ecommerce. Everything from concept, design, programming, ui, marketing & seo, analytics, hosting up to business consulting. I prefer using open source software like typo3 or magento but i also admire the easiness of saas software and services like squarespace. I spend most of my spare time up in the Alpes.

Link to comment

Solution with Javascript based on built in YUI3.


The proof of concept is here, but not yet online, as it is not translated yet. You need a password to open it.http://www.inselhostel.com - Password: inselhostel

This solution has the following features:

  • as many languages you want to
  • add and delete pages in configured languages with automatically adapted menues
  • works automatically for primary and secondary navigation
  • easy configuration of new languages
  • while translating into a new language or translating a new page, these pages do not appear on your site
  • you can create a fully styleable and customizable language menue
  • no extra cost for external services
  • no template restrictions: should be adaptable to each template
  • SEO works: Google uses natural language detection and pages do physically exist under unique urls

alt text


Quick step by step tutorial:


1) Create your pages in Squarespace.Use iso language codes to for defining unique url slugs per page in the page settings. Translate the url slugs to the respective language. For example:


**en**/index
**de**/index
**en**/folder/index
**de**/ordner/index
**en**/folder/page
**de**/ordner/seite




alt textThe DE--- and EN--- Pages in the tree are just a visual orientation help without function. Just disabled pages oder folders.


2) Inject the javascript snippet described below in Settings > Advanced > Injection > Footer and configure the script to your needs. This will be explained below step by step. Check your site, if the menues are display correct. Check with debugger for JS errors.

3) Create your language switch.

Solution 1-3 require no coding skills. Solution 4 requires css and js skills.

a) Solution 1: Create a cover page with a button or link for each language.

b) Solution 2: Create the language menue within the main navigation


Examle structure for two lanuges
----------------------------------------------------------------
label           Url Slug            Page Type
----------------------------------------------------------------
EN          /en/language        Folder
   English     /en/index       Page / Link / Index
   Deutsch     /de/index       Page / Link / Index

DE          /de/language        Folder
   English     /en/index       Page / Link / Index
   Deutsch     /de/index       Page / Link / Index

c) Solution 3: Create the language menue in the secondary navigation if supported by your template


Examle structure for two lanuges
----------------------------------------------------------------
label           Url Slug            Page Type
----------------------------------------------------------------
English         /en/index       Page / Link / Index
Deutsch     /de/index       Page / Link / Index

English         /en/index       Page / Link / Index
Deutsch     /de/index       Page / Link / Index

d) Solution 4: create menue dynamically with yui, javascript and customize it for your needs and template. Inject custom CSS in Squarespace. You may use a flag sprite to display country flags in language menue. Example CSS posted below.

Full script snippet



<script>
/* LANGUAGE MENUE IN SQS WITH YUI3
** (c) Raphael Boos, soft.works 2015
** Version: 1.0
** Inject in Settings > Advanced > Code Injection
** Easy Language Menues in SQS
** Convention: first level of all URL Slugs is language separator
** Expects predefined html structures: #mobileNavigation|#mainNavigation|#secondaryNavigation > div > a|label
** Old code: var allowedLanguages = ['de','en']; if(allowedLanguages.indexOf(urlparts[0]) != -1){
*/
YUI().use('node', function (Y) {

 // output a menu
 var output = false;

 // set default language
 var language = "de";

 // define languages
 var allowedLanguages = new Array();
 allowedLanguages['de'] = {
       label:'Deutsch',
       short:'DE',
       url:'/de/index',
       flag:'<i class="flag-icon flag-icon-de"></i>',
       lang:'de-DE'
 };
 allowedLanguages['en'] = {
       label:'English',
       short:'EN',
       url:'/en/index',
       flag:'<i class="flag-icon flag-icon-en"></i>',
       lang:'en-GB'
 };

 // detect current language
 var urlparts = document.location.pathname;
 if(urlparts.startsWith("/")){
   urlparts = urlparts.substr(1);
 }
 if(urlparts.endsWith("/")){
   urlparts = urlparts.substr(0,urlparts.length-1);
 }
 if(urlparts.length) {
   urlparts = urlparts.split("/");
   if(urlparts[0] in allowedLanguages){
     language = urlparts[0];
   }
 }
 var selector = [
   '#mainNavigation > div > label:not([data-href*=\"/' + language + '/\"])', 
   '#mainNavigation > div > a:not([href*=\"/' + language + '/\"])', 
   '#mobileNavigation > div > label:not([data-href*=\"/' + language + '/\"])', 
   '#mobileNavigation > div > a:not([href*=\"/' + language + '/\"])',
   '#secondaryNavigation > div > label:not([data-href*=\"/' + language + '/\"])', 
   '#secondaryNavigation > div > a:not([href*=\"/' + language + '/\"])'
 ]; 

 // remove all nodes not in current language
 Y.all(selector.join()).get('parentNode').remove();

 // output: append to main and mobile navigation
 if(output){   
   Y.all('#mainNavWrapper,#mobileNavWrapper').append(buildLanguageMenuHTML(language, allowedLanguages, 'right top'));
 }

 // adapt html lang attribute
 Y.one('html').setAttribute('lang', allowedLanguages[language].lang);
});

function buildLanguageMenuHTML(strCurrentLang, arrAllowedLangs, strClass){
   var htmlTemplate = '<nav id="langNavigation" class="' + strClass + '"><div class="folder"><input type="checkbox" name="folder-toggle-lang-navigation" id="folder-toggle-lang-navigation" class="folder-toggle-box hidden"><label for="folder-toggle-lang-navigation" class="folder-toggle-label" onclick="" data-href="' + arrAllowedLangs[strCurrentLang].url + '">' + arrAllowedLangs[strCurrentLang].short + '</label><div class="subnav">###languages###</div></div></nav>';
   var htmlTemplateInner = '<div class="collection"><a href="###url###">###label###</a></div>';
   var htmlInner='';
   var htmlOutput='';
   for(language in arrAllowedLangs){
       if(arrAllowedLangs.hasOwnProperty(language)){
           htmlInner += htmlTemplateInner.replace('###label###', arrAllowedLangs[language].flag + arrAllowedLangs[language].label).replace('###url###',arrAllowedLangs[language].url);
       }
   }   htmlOutput = htmlTemplate.replace('###languages###',htmlInner);
   return htmlOutput;
}
</script>

Explanation of the script STEP by STEP

a) This load the YUI node module you need for manipulation


YUI().use('node', function (Y) {

b) If output is true a menue is output. You have to adapt the menue output for your template.


  // output a menu
 var output = false;

c) Define your default language. The language key must be the same used in the URL slugs.


  // set default language
 var language = "de";

d) Define all allowed lanuages and configure them for your needs.Each key in the array 'de' or 'en' represents one language and is the same used for your url slugs.

  • label is used for menue output
  • short is used for menue output
  • url is the start url slug for each language
  • flag is a html snippet i use to render a language flag with css and a sprite.
  • lang is used for the manipulation of the html lang attribute

    // define languages var allowedLanguages = new Array(); allowedLanguages['de'] = { label:'Deutsch', short:'DE', url:'/de/index', flag:'', lang:'de-DE' }; allowedLanguages['en'] = { label:'English', short:'EN', url:'/en/index', flag:'', lang:'en-GB' };

e) Here we detect the curent language, if not configured we use the default language.


  // detect current language
 var urlparts = document.location.pathname;
 if(urlparts.startsWith("/")){
   urlparts = urlparts.substr(1);
 }
 if(urlparts.endsWith("/")){
   urlparts = urlparts.substr(0,urlparts.length-1);
 }
 if(urlparts.length) {
   urlparts = urlparts.split("/");
   if(urlparts[0] in allowedLanguages){
     language = urlparts[0];
   }
 }

f) This is the most tricky part. Probably you will have to adapt this for your template.


  var selector = [
   '#mainNavigation > div > label:not([data-href*=\"/' + language + '/\"])', 
   '#mainNavigation > div > a:not([href*=\"/' + language + '/\"])', 
   '#mobileNavigation > div > label:not([data-href*=\"/' + language + '/\"])', 
   '#mobileNavigation > div > a:not([href*=\"/' + language + '/\"])',
   '#secondaryNavigation > div > label:not([data-href*=\"/' + language + '/\"])', 
   '#secondaryNavigation > div > a:not([href*=\"/' + language + '/\"])'
 ]; 

g) All menue elements that do not belong to the detected language are removed from the page menue.


  // remove all nodes not in current language
 Y.all(selector.join()).get('parentNode').remove();

h) Here the output flag is checked and if true the function for menue creation is called


  // output: append to main and mobile navigation
 if(output){   
   Y.all('#mainNavWrapper,#mobileNavWrapper').append(buildLanguageMenuHTML(language, allowedLanguages, 'right top'));
 }

i) The html lang attribute is adapted


  // adapt html lang attribute
 Y.one('html').setAttribute('lang', allowedLanguages[language].lang);
});

j) The function for building the menu. This function builts a dropdown menue with default SQS dropdown markup.Parameters of the function:

  • strCurrentLang - Current Language
  • arrAllowedLangs - array with configured language
  • strClass - injects css Classes to the nav Tag to define the position. Example CSS will be posted below.

CSS Example


You have to adapt CSS and output for your template


#headerNav #langNavigation .folder-toggle-label{
   background: #1d1a1a;
   border-radius: 50px;
   padding: 0;
   line-height: 3em;
   width: 3em;
}
#headerNav #langNavigation.top{
 top:-3px;
}
#showOnScrollWrapper #langNavigation  .folder-toggle-label{
   background: #292525;
   border:5px solid #292525;
}

#langNavigation{
   position: absolute;
   z-index: 10050;
}
#langNavigation.right{
   right: 0;
}
#langNavigation.left{
   left: 0;
}
#langNavigation.top{
   top: 0;
}
#langNavigation.bottom{
   bottom: 0;
}
html:not(.touch-styles) body:not(.always-use-overlay-nav) .nav-wrapper #langNavigation.right .folder .subnav {
   left: auto;
   right: 0;
}

/* FLAG ICONS FOR LANGUAGE MENU
** svg images+css from http://lipis.github.io/
** upload images to SQS and use static url for referencing
** add as many languages you need
*/
.flag-icon {
   background-size: contain;
   background-position: 50%;
   background-repeat: no-repeat;
   position: relative;
   display: inline-block;
   width: 1.33333333em;
   line-height: 1em;
   height: 1em;
   font-size: .85em;
   margin-right: .5em;
}
.flag-icon-de {
 background-image: url(//static1.squarespace.com/static/56b1f8b060b5e9f4fa0f2143/t/56b33d8ae32140d4e6e85a10/1454587288318/de.svg);
}
.flag-icon-en {
 background-image: url(//static1.squarespace.com/static/56b1f8b060b5e9f4fa0f2143/t/56b33dc0e32140d4e6e85ab9/1454587328016/gb.svg);
}



multilingualinselhosteldesktopdropdown.jpg.07b4dc6d356e5f9e2f703f5996179f5c.jpg

multilinguainselhostelbackend.png.efe3b81dfe0547aa47dbfa7f3cbc18ee.png

Edited by softworks
Initial Revision

I am a freelance developer situated in southern germany. I offer full service websites, ecommerce. Everything from concept, design, programming, ui, marketing & seo, analytics, hosting up to business consulting. I prefer using open source software like typo3 or magento but i also admire the easiness of saas software and services like squarespace. I spend most of my spare time up in the Alpes.

Link to comment

This code was used together with the PACIFIC template. The configured selectors have to be adapted for other templates. If anyone uses this code with other templates please post the selectors here.

Any improvements are welcome.

Thank you.

I am a freelance developer situated in southern germany. I offer full service websites, ecommerce. Everything from concept, design, programming, ui, marketing & seo, analytics, hosting up to business consulting. I prefer using open source software like typo3 or magento but i also admire the easiness of saas software and services like squarespace. I spend most of my spare time up in the Alpes.

Link to comment

Hi @softworksThank you so much for your post. I'm trying to use this code for the template FIVE. I'm not a coder so I'm trying really hard that this works. I added the code to the custom css and the snippet to the code injection header. Right now it shows the english and german menu on top, so I don't know exactly what else I have to change. Can you give me a tip how I can make it work in the template FIVE? I would really appreciate your help!!Thank you so much!

Link to comment

Hallo @hausecec

Template FIVE Adaptions

  1. You need to adapt the Javascript as described in f) as each template has another html structure.
  2. You need to adapt the CSS as stated in the post as each template has another html structure

Adaption of Javascript

a) Change the selector variable. Because i cannot see in the five demo if there is a secondary navigation, perhaps you need to add the code for the secondary navigation if you need a multilingual secondary nav.


   var selector = [
    '#mainNavigation > ul > li > a:not([data-href*=\"/' + language + '/\"])', 
    '#mobileNavigation > ul > li > label:not([data-href*=\"/' + language + '/\"])', 
    '#mobileNavigation > ul > li > a:not([href*=\"/' + language + '/\"])'
  ]; 

b) Change the output injections point in case you want to use the dropdown menu: you have to try this out and you have to adapt the css for the injection point.


// output: append to main and mobile navigation
  if(output){    
    Y.one('#page-header-wrapper').append(buildLanguageMenuHTML(language, allowedLanguages, 'right top'));
  }



Adaption of CSS

You need to adapt the css for the injection point.


#page-header-wrapper #langNavigation .folder-toggle-label{
    background: #1d1a1a;
    border-radius: 50px;
    padding: 0;
    line-height: 3em;
    width: 3em;
}
#page-header-wrapper #langNavigation.top{
  top:-3px;
}



Edited by softworks
Initial Revision

I am a freelance developer situated in southern germany. I offer full service websites, ecommerce. Everything from concept, design, programming, ui, marketing & seo, analytics, hosting up to business consulting. I prefer using open source software like typo3 or magento but i also admire the easiness of saas software and services like squarespace. I spend most of my spare time up in the Alpes.

Link to comment

@octopus - I agree with some points but not with all.

  1. The "ridiculously bloated" code could be written shorter. But it is readable and understandable. If you have ideas to improve it - don't hesitate to post your ideas.
  2. Whats wrong with duplication - SQS does the same. It is not the best technically.
  3. It does not offer side by side translation.
  4. You can create each language with a different structure.
  5. Right, blog elements not translated - easy to map them in js or use css. Answers are here in the forum. (I did not use the blog in the sample project).

I am a freelance developer situated in southern germany. I offer full service websites, ecommerce. Everything from concept, design, programming, ui, marketing & seo, analytics, hosting up to business consulting. I prefer using open source software like typo3 or magento but i also admire the easiness of saas software and services like squarespace. I spend most of my spare time up in the Alpes.

Link to comment
  • 2 weeks later...

Hey @Softworks, thanks for your code. It's really the best option for me to create a multilingual site.

One question; did you add some custom css to get the mobile navigation menu right? For me, the langNavigation folder is displayed at the top right. I would like to have it under the other navigation links just like you. How did you manage that?

Thanks for the help! Grtz Bart.

Edited by bart-ostyn2
Initial Revision
Link to comment
  • 2 weeks later...

In the Hayden template the switching of the language works perfectly but the actual switcher (I believe it's the #langNavigation) does not show up.Here is the photo showing only Squarespace's default menu, even after having inserted all the code and the flags:

alt textI uploaded the flags as PNG with the correct names ('en' and 'de'), as SqSp does not allow SVGs as files. I also inserted the above CSS and JS snippets in the correct places. I checked in the Chrome DevTool and I saw that the JS is correctly present but does not append any #langNavigation (well, anything at all actually) to the DOM. Maybe it's just matter of adjusting the selectors but I have no idea how to do it :)Would you or anyone be so kind to adapt the above code for the Hayden template? That would be awesome!!!

PS. In the attached img, on the left, there is just the logo. I just erased it, as it's not relevant to our topic.

foto.png.3a798cd3773d2fd498e89aa48ab5e17a.png

Link to comment
  • 4 weeks later...
Guest Yambo

Hi softworks,

Amazing stuff. This is exactly what I am looking for. However I really suck at coding. Seem to be struggling with something. Is it possible to have the language setup as Index (checkout website: www.knoblejourney.com) as I want a one page scroll option for each language. Doing EN, FR, ESP, DE. NEED YOUR HELP! :)

Kind regards

Y.

Link to comment
  • 2 weeks later...

We have been trying pretty much all solutions posted above for the past couple months. I also appreciate your attempt to fix SquareSpace with your script but this is not a good solution for us :)

Our last hope was to use LocalizeJS which seemed very promising (even though it gets quickly quite expensive). After a couple days we had our website in two languages. Defaults to french, option to switch to english.

But here is the trick: when using LocalizeJS the pages in each language have the same URL. This is just unacceptable for SEO. Google is simply not able to see our website in english, which is dramatic since almost 30% of our revenue comes from english-speaking countries. And even if Google was able to find and run the JavaScript provided by LocalizeJS, it could not attach a unique URL for a given language.

I reached out to LocalizeJS support and they suggested that we tweaked their loading script to detect either a subdirectory (mycompany.com/en) or a subdomain (en.mycompany.com) and load the appropriate language. Since the subdirectories solution does not work with SquareSpace (the menu is built automatically) I tried to configure a subdomain.

But here again there is catch: SquareSpace will redirect any subdomain (or alternative domain) to the main domain name. Therefore en.mycompany.com redirects immediately to www.mycompany.com.

Conclusion: we have decided for now to create a second website, in english this time, until SquareSpace adds support for localization... or until another high-quality website builder supports localization.

I hope my investigation can save you some time :)

Edited by guillaume.zurbach@gmail.com
Initial Revision
Link to comment

Hi @softworks, this code looks great, and for the most part it is working for me. However, the langNavigation (as I think it is called) does not show up in my website. Is there something wrong in the code? I am using Horizon which is a variant of Pacific so it should work exactly how you wrote it, except that I changed DE to NO. It successfully hides the links for the other language, but there is no language selector menu showing.

Here is my website, under construction still: https://bergen-adventistkirke.squarespace.com. The English one works best right now as I still need to fix the other.

Link to comment

Hi @softworks, this code looks great, and for the most part it is working for me. However, the langNavigation (as I think it is called) does not show up in my website. Is there something wrong in the code? I am using Horizon which is a variant of Pacific so it should work exactly how you wrote it, except that I changed DE to NO throughout the code. It successfully hides the links for the other language, but there is no language selector menu showing on the right. I also already uploaded the flag images and copied your exact CSS into my CSS editor.

Here is my website, under construction still: https://bergen-adventistkirke.squarespace.com.

I currently added a different dropdown menu with links in order to navigate to the languages for now. But it does not look like your selector menu, detached from the main navigation on the right, and I haven't figured out how to add flags. Any help to get the language selector menu functioning how you made it would be greatly appreciated! Thanks!

Edited by musicaldesigner
Link to comment

Hi @softworks, thanks for the code and explanations above, I'm sure this is helping many people wanting to build multilingual sites.

I'm completely new to squarespace and I have no coding knowledge. I've tried following your steps and explanations but it's not working. I'm using the Nueva template to build a multilingual site (4 languages). Does the code above work for the Nueva template or are there many changes that need to be done in order for it to work? For me it's not working, but it maybe be because I'm a complete novice in coding and I'm not implementing each step where it should go...

On top of that I need my footer to be page specific for each language, but the Nueva template doesn't offer specific footer content for each page, therefore if I translate the footer in the English section for example, it will do so for every page, resulting in a Spanish content page with an English footer for example. I see that you've managed to do this for your website http://www.inselhostel.com but I'm not sure if it's because your template allowed this or because you've implemented a code...

Can you or anyone help me out here. I would be so greatful! ThanksMy site underconstruction: https://joaquim-benet.squarespace.com/

Link to comment
  • 2 weeks later...

@joaquimbenetI would have definitely tried the solution offered in this post. But at the time I created my bilingual site it wasn't yet available. Therefore I opted for the multilingualizer. It checks the language settings of the browser thus offering the visitor the pages in their language as you can check out here www.ufw-photography.com

Link to comment
  • 2 months later...

Hi softworks.

Thank you so much for your work - Danke Schön! I really need it as I am not a coder either. I am using FIVE as well, and have tried performing the adaptations, you have proposed, but I cannot get it to work. Can you help out in any way? My site is (currently): ledreborg-slot.squarespace.com.

All the best

Link to comment

@softworks

I'm really not a coder, but step one:


 **en**/index
**de**/index
**en**/folder/index
**de**/ordner/index
**en**/folder/page
**de**/ordner/seite

Where do I copy that code to.

I hope you can help me out

Link to comment
  • 1 month later...

I am not sure what exactly is wrong but this code doesn't work for me at all. Makes no changes to my website. I have followed the instruction and read all teh following comments as well. Please help me figure it out.

  1. Using "Mercer" theme. Maybe it doesn't support the code. How can I check if it's the theme?

  2. "CSS Example" - This CSS code, i'm not sure if i have to implement it for this script to work. But because of a lack of any indication or a path it has to be implemented, i assume it's optional and exists for functionality adjustment.Tried Inserting this CSS code into "Custom CSS" in "Design" menu just for the sake of it. As expected, it didn't work.

  3. Have changed "output a menu" to "true" but it still doesn't work.

Maybe there is something else I can try?

Edited by Ice_Ivanov
Initial Revision
Link to comment
  • 1 month later...
  • 3 weeks later...

Dear @softworks,Look this simple test site ....that I have create to try .... with MARQUE template.

Enter in squarespace and ...:Login: info@tonylanzillo.itPassword : antonio

I have cover page...to link in italian site or english site...The english site is: index "welcome" and folder "service" with page "reservation" The Italian site is: index "benvenuto" and folder "servizi" with page " prenotazioni"

I would when in cover page click eng ...go in english site with only menù english (welcome ,service/reservation) while i click ita go in italian site with only menù italian (benvenuto, servizi/prenotazioni)

I know that with simple css code .....italian site hide in english version and english site hide in italian version.

Please help me :)ThanksAntonio

Link to comment

Dear @softworks, I have built a website in Squarespace, using Five template and it needs to be in English and Spanish. I like your solution and would like to implement it, however I am not a developer. How much would you charge to do this for me? I can create the English and Spanish pages as per your tutorial, step 1. Thanksstuart@setthescreen.com

Link to comment
  • 2 weeks later...
  • 2 months later...

@softworks or anyone else - I'm having the same issue with the Bedford Template. I think it's determining horizontal vs vertical appearance of the main nav based on the width of the menu items for both languages. If I only have 3 items for each language, the nav is horizontal like I want it (all 6 items would fit horizontally too which I think is why it works). As soon as the items for both languages won't fit horizontally, the menu appears vertical even though the items for one language will fit horizontally without a problem. Can I fix this through CSS or insert the code somewhere else?

Edited by egt
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

×
×
  • Create New...

Squarespace Webinars

Free online sessions where you’ll learn the basics and refine your Squarespace skills.

Hire a Designer

Stand out online with the help of an experienced designer or developer.