Translating a Magento PWA Venia Theme

  1. Basic Translation

Supporting different languages is a must for merchants that are targeting customers from different countries and/or languages.  Leading also to bigger exposition since the customer base would be significantly expanded.

Venia / Magento PWA theme doesn’t provide internationalization packages out of the box; being the American English the default language (en_US); however, the good news is that translating a Venia web site is a very simple process. 

Let’s take for example the Search button, located at the top right of any recently installed Venia environment, and translate it to Spanish. 

Assuming that the local project has been fully configured:

  1. Copy the original en_US from Venia and paste it into the project root

# cp project_root/node_modules/@magento/venia-ui/i18n  /local_project

  1. Create a new dictionary using the following format: 

language-abreviation_country.json

Example:

es_MX.json

zh_TW.json

  1. Replace the English content with the required translations; let’s use es_MX for Mexican Spanish.

Example:

Original:

“searchTrigger.search”: “Search”

Translation:

“searchTrigger.search”: “Buscar”

  1. Recompile and re-start Venia (development or production are both fine).

After this, the Search button will be fully translated into Spanish.

  1. Custom Translation / Advanced Translation

When attempting to translate new words, extra steps are required in order to translate those new words.

The most simple procedure would be as follows:

  1. Add a new id to both the en_US.json and the custom translation file located in the local root project. The id can follow any pattern.

Example:

en_us.json:

“menu.men”: “Men”

custom.json:

“menu.men”: “Hombres”

2 In the code the following changes need to be made in order to translate the new word.

Example:

import {FormattedMessage} from “react-intl”;

let trans = (

   <FormattedMessage

       id={‘menu.men’}

       defaultMessage={‘Men’}

   />

);


// In this case “trans” is just a variable to hold the translation text result.

3. Recompile and re-start Venia (development or production are both fine.

After this, the custom translation will be used in every component where the custom id is being used.

Finally, the translation process could require more complex steps such as: API calls, coding, etc; but for the steps described above would cover most scenarios on any startup project.

Also, remember to include a custom dictionary as soon as the backend server has enabled it, since some versions of Venia might explicitly expect a dictionary when the backen is using a language different than en_US.

Fastly CDN With Any Magento (Open Source and Commerce On-Premise)

Introduction

Magento generally is not known for the fastest one on the block but this has now changed. Starting from a couple years ago Magento suggested the use of Varnish on production for caching storage and it will significantly increase the speed of your Magento site.

Fastly in addition to its CDN and firewall capabilities, it also includes Varnish functionality. Fastly does mention that it uses Varnish as its core, so it’s basically an advanced and distributed Varnish server. Fastly accelerates the website speed with its CDN networks and caching storage. If Cloudflare is famous for its (free and) fast CDN, Fastly also integrates pretty well with Magento’s full page caching.

We know that Magento Commerce Cloud includes Fastly on its bundle, but now your self-hosted Magento Open source and Magento Commerce sites can also have Fastly. Read more to see how easy it is to configure Fastly for Magento Open Source / Commerce on-premise.

Requirements

Here are the things that you will need to integrate Fastly into self-hosted Magento:

  1. A running Magento 2.3 / 2.4 of Open Source / Commerce On-Premise edition with composer installed
  2. A basic understanding of Magento admin configuration (including cache cleaning)
  3. A registered account on https://www.fastly.com (we tested both free developer trial and paid accounts)
  4. A working Magento 2 Access Key https://marketplace.magento.com/customer/accessKeys/ 
  5. A Fastly Personal API Token with global scope: https://manage.fastly.com/account/personal/tokens 

Extension installation

Installing Fastly’s Magento extension is a straightforward process. Just like any other Magento extensions, you can do the following steps:

  1. Go to https://marketplace.magento.com/fastly-magento2.html 
  2. Select your magento version and checkout:
  3. Now login to your server and go to the root directory of your Magento
  4. Paste the access key in your auth.json file inside your magento install:
  5. Now execute sudo -u www-data composer require fastly/magento (see that I’m using sudo -u www-data to avoid messing with file permission)
  6. Clean magento cache with sudo -u www-data bin/magento cache:flush

Finished! Now you should be able to see Fastly module in Magento admin under Stores – Configuration – Advanced – System – Full Page Cache and you will have a new option called Fastly CDN under Caching Application:

Fastly basic configuration

In order to get your site served by Fastly, you will need to add a new Fastly service and a host. To create a new service, follow these steps:

  1. Login to your Fastly account
  2. Click on Create Service button right on the top right of your dashboard
  3. Insert the domain that you want to use then click Add

To create a new host, do the following:

  1. Click on Origins link on the left sidebar
  2. Insert the host IP address or the hostname, then click Add. Once you have the host configured, then you are ready to do the Magento extension configuration.

Magento extension settings

Once you’ve configured service and host on Fastly, you can go to Stores – Configuration – Advanced – System – Full Page Cache of your Magento admin and you will have a new option called Fastly CDN under Caching Application.

  1. Copy the service ID from your newly-created Fastly service to Fastly Service ID field
  2. Do the same thing for the Fastly API Token (described in the requirement section at the top of this article)
  3. Verify the details by clicking on Test credentials
  4. Save Config – Flush Magento cache
  5. After save, go back to the previous Fastly configuration, then click on Upload VCL to Fastly, tick on Activate VCL after upload, then click Upload
  6. Once again Save Config and Flush Magento cache

Fastly uses VCL for its service configuration. You can always write it by hand, but this Magento extension will do it for you. The only thing that you need to do is make sure to upload VCL after changing any Fastly Configuration.

At this point, Magento should be ready to work with Fastly but you won’t be able to test it until you update your DNS record as explained below.

DNS Configuration

Fastly acts as a proxy for your server. All web requests going to your domain will go through Fastly before actually reaching your server. This way, Fastly can apply firewalls, manipulate requests, filter traffic, and others. In order to do that, you will need to point the domain to Fastly hostname instead of your server directly. 

Fastly has several different hostnames that you can choose depending on your SSL/TLS configuration and/or whether you choose to limit your traffic to a certain network. More details here: https://docs.fastly.com/en/guides/adding-cname-records#choosing-the-right-fastly-hostname-for-your-cname-record

Friendly warning reminder: once you change the DNS, it literally means the traffic will start flowing through the new Fastly service. If you are on production, make sure that everything is good before you switch the DNS.

In short, if you don’t want to use Fastly TLS, then use nonssl.global.fastly.net.

If you need to try Fastly TLS without paying anything, use [name].global.ssl.fastly.net.

And if you already enabled paid account and want to use fully-working fastly TLS, use j.sni.global.fastly.net or k.sni.global.fastly.net.

More details here: https://docs.fastly.com/en/guides/adding-cname-records#tls-enabled-hostnames

Please note that once you change the DNS, it might take some time for the whole internet to propagate your new domain configuration.

If everything goes well, you will be able to start seeing live traffic statistics on your Fastly dashboard. Also, don’t forget that your Magento site is now blazing fast!

Fastly X Magento overview

Overall, we love Fastly. We have been using Cloudflare for our clients and we will also offer Fastly integration for our clients soon. Fastly offers something that Cloudflare doesn’t: seamless Magento integration. Based on our test, Magento running Luma theme can be fully loaded in nearly the blink of an eye. Magento has never been this fast.

Using Fastly is also a timesaver rather than configuring and maintaining your own Varnish server. You probably need to pay at least USD 50 / month for a Fastly paid account while you can build a Varnish server under USD 10 / month, but remember the maintenance cost and all the hassle that you will need to do in the future.

That cost consideration also come in to play when you need to enable something like Image Optimizer. Fastly has it, too and we have confirmed that it is integrated with the Magento extension pretty well.

If you have a need for speed for your high-traffic Magento, go with Fastly. Contact us for assistance and we’re ready to help.

Testing Magento 2.3~2.4 on Windows: Making the admin panel work

The official documentation from Adobe doesn’t clearly state that Magento 2 can be installed on a Windows environment; however many tutorials found on the Internet still demo Magento 2 on a Windows environment.

Developers with no experience on Linux might have difficulties when trying to evaluate Magento 2 for the first time, so it is understandable to try an installation on a Windows environment to start taking their first steps into Magento 2.

This document assumes that Magento 2.3.x or 2.4.x is already installed in a full Windows environment (no VM or docker involved), so the installation process will be skipped in this article.

Since Windows is not the recommended environment for installing Magento, problems after a fresh install might be common. The first issue you would face after installing Magento 2.3.x or 2.4.x is the admin site display.

Ooops…. Now what?

When exploring the page via Developer Tools it is clear that something went wrong when loading the page scripts and theme.

The solution for this is tricky and the errors don’t tell that much for troubleshooting; however, remember that the recommended environment for installing Magento 2 is Linux; and that might be a good indication on how to deal with the problem.

One of the files in charge of loading the theme is Validator.php, located at vendor\magento\framework\View\Element\Template\File; inside there is the following function that validates if the current Magento path is related to the directory.

protected function isPathInDirectories($path, $directories)

 {

        if (!is_array($directories)) {

            $directories = (array)$directories;

        }

        $realPath = $this->fileDriver->getRealPath($path);

        foreach ($directories as $directory) {

            if (0 === strpos($realPath, $directory)) {

                return true;

            }

        }

        return false;

 }

Inside the foreach loop let’s compare the params $realPath and $directory passed to the strpos function:

echo $realPath;

installation\path\vendor\magento\module-backend\view\adminhtml\templates\page\js\require_js.phtml

echo $directory;

installation/path//var/view_preprocessed/pub/stat/

Did you notice? The slashes are in different directions, causing the isPathInDirectories to return false all the time.

The reason for this is that getRealPath will return the correct slash format for the current OS, being the backslashes the format for Windows file paths, while $directory is just considering the Linux convention; so the solution would be to use the same getRealPath function for converting the $directory variable into the correct Windows file format.

protected function isPathInDirectories($path, $directories)

{

     if (!is_array($directories)) {

     $directories = (array)$directories;

}

$realPath = $this->fileDriver->getRealPath($path);

foreach ($directories as $directory) {

    $directory = $this->fileDriver->getRealPath($directory);

    if (0 === strpos($realPath, $directory)) {

        return true;

    }

}

return false;

}

After this quick fix you can just refresh the browser for normally displaying the admin login page.

However, please be noted that the solution proposed here is just testing purposes. If you want to make the changes permanently you must follow the Magento developer standards for developing a plugin or preference.

Content Security Policies on Magento: Fixing Yotpo policies errors

Yotpo is a useful platform built-in into Magento that helps merchants to easily collect and display customer reviews, photos and videos, improving customers’ trust; therefore boosting sales.

Although, Yotpo is fully integrated and configured to work with Magento it is not error free after a clean installation; being the most common issue related to Content Security Policies (CSP).

CSP are a security tool to mitigate site attacks such as: card skimmers, session hijacking, clickjacking, and more. Requiring the server to previously whitelist in the HTTP headers the external sources for scripts, styles and other resources.

When a SCP security issue occurs a developer might see an error message appearing the browser developer console, being very similar to the following one:

[Report Only] Refused to load the script ‘https://xxxx’ because it violates the following Content Security Policy directive: “xxxx”.

For fixing this error, the first thing we need to do is to add a etc/config.xml and configure the SCP endpoints for admin and storefront.

<?xml version=”1.0″?>

<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:module:Magento_Store:etc/config.xsd”>

   <default>

       <csp>

           <mode>

               <storefront>

                   <report_only>1</report_only>

               </storefront>

               <admin>

                   <report_only>1</report_only>

               </admin>

           </mode>

       </csp>

   </default>

</config>

Next, we need to create etc/csp_whitelist.xml that will have the main configuration to the whitelist resources for the different CSP policies. Usually, for Yotpo make sure to add all the following policies:

<?xml version=”1.0″?>

<csp_whitelist xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:module:Magento_Csp/etc/csp_whitelist.xsd”>

   <policies>

       <policy id=”script-src”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

           </values>

       </policy>

       <policy id=”connect-src”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

           </values>

       </policy>

       <policy id=”frame-src”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

           </values>

       </policy>

       <policy id=”form-action”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

           </values>

       </policy>

       <policy id=”img-src”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

           </values>

       </policy>

       <policy id=”style-src”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

           </values>

       </policy>

       <policy id=”font-src”>

           <values>

               <value id=”yotpo_main” type=”host”>yotpo.com</value>

               <value id=”yotpo_main_www” type=”host”>www.yotpo.com</value>

               <value id=”yotpo_p” type=”host”>p.yotpo.com</value>

               <value id=”yotpo_staticw2″ type=”host”>staticw2.yotpo.com</value>

               <value id=”yotpo_w2″ type=”host”>w2.yotpo.com</value>

               <value id=”gstatic” type=”host”>*.gstatic.com</value>

           </values>

       </policy>

   </policies>

</csp_whitelist>

With this, we are expliciting whitelisting the external sites ot be allowed to provide resources to our site, helping to prevent malicious scripts from unknown sources attempting to:

  • Send credit card info to an attacker’s website.
  • Make users click on elements that are not supposed to be on page.

Do noy forget that for installed 3rd parties modules, you might need to check with the vendor/developer for getting more information on what dns you should whitelist.

Basic Elasticsearch troubleshooting

Since Magento 2.4.0, Elasticsearch has become the default indexation tool; however, some small issues might occur as well; being the most important not able to index correctly, requiring some Linux skills. If after executing a reindex you consider the performance of the indexing has been decreased this article might help you.

The first step is to check if ElasticSearch is running correctly by executing “curl -X GET” as follows:

If you don’t get the ElasticSearch information that means you are not connected to the cluster, so please check your connectivity and/or try to restart the ElasticSearch service/server.

The same curl command provides more powerful options for browsing the current indexes.

The display of the CURL GET command by the index would be very long but it will give an idea of how healthy your service/server is.

If you still consider that not all indexes are being handled correctly you can delete all indexes with the DELETE option.

The above “acknowledged” message means that all indexes have been deleted; letting you trigger a new re-index and let ElasticSearch rebuild itself.