Nuxt and i18n: Google showing mixed language results - internationalization

I've made a site using Nuxt.
The site has 2 languages: Italian (default) and English for everyone else.
I installed nuxt-i18n and configured it, and everything seems to work fine (especially when looking at the code with the devtools, html lang, rel=alternate and so on..).
But here's the problem: when i search for the site with google (in italian), the snippet for the site in the SERP is in english.
Here's my code:
['nuxt-i18n', {
seo: false,
baseUrl: 'https://www.leconturbanti.it',
locales: [
{
name: 'Italiano',
code: 'it',
iso: 'it-IT',
file: 'it-IT.js'
},
{
name: 'English',
code: 'en',
iso: 'en-US',
file: 'en-US.js'
},
],
pages: {
'contatti/index': {
it: '/contatti',
en: '/contact-us'
},
'illustrazioni-collezione/index': {
it: '/illustrazioni-collezione',
en: '/illustrations-capsule'
}
},
langDir: 'lang/',
parsePages: false,
defaultLocale: 'it',
lazy: true
}]
I set seo: false for better performance as explained in the docs, and merge the data in the default layout:
head(){
return{
script:[
{type: `text/javascript`, innerHTML: this.$t('policy.cookieId')},
{src: `//cdn.iubenda.com/cs/iubenda_cs.js`, charset: `UTF-8`, type: `text/javascript`}
],
__dangerouslyDisableSanitizers: ['script'],
...this.$nuxtI18nSeo()
}
},
I also set the meta tags for every page with $t in the head(). For example, in home:
head(){
return{
title: this.$t('seo.home.title'),
meta: [
{ hid: 'description', name: 'description', content: this.$t('seo.home.description')},
{ hid: 'og:title', property: 'og:title', content: this.$t('seo.home.title') },
{ hid: 'og:url', property: 'og:url', content: this.$t('seo.home.url') },
{ hid: 'twitter:title', property: 'twitter:title', content: this.$t('seo.home.title') },
{ hid: 'og:description', property: 'og:description', content: this.$t('seo.home.description') },
{ hid: 'twitter:description', property: 'twitter:description', content: this.$t('seo.home.description') },
]
}
},
I can't understand what i did wrong. I already added the site in Search Console. If you need to visit it for inspection, the url is: www.leconturbanti.it
If you need more of my code in order to answer just ask.
Thank you.

Found out that this issue is from nuxt-i18n itself.
The problem is that the Google Crawler will fallback to the english version of a page, and this not good if you have another locale as default.
More here.
For now, until the problem is solved, the workaround I used is to disable the auto detect language to avoid the redirect with detectBrowserLanguage: false.

My nuxt page head:
head(){
return {
...this.$nuxtI18nHead({ addDirAttribute: true, addSeoAttributes: true }),
title: this.page.title,
meta: [
{
property: 'og:description',
name: 'description',
content: this.page.description
},
{
property: 'og:title',
name: 'title',
content: this.page.title
}
],
}
},
My nuxt.config.js
i18n: {
locales ,
strategy: 'prefix',//no_prefix , prefix , prefix_and_default ,prefix_except_default
vueI18nLoader: true,
defaultLocale: process.env.LOCALE_DEFAULT||'en',
langDir: '~/locales/',
vueI18n: {
silentTranslationWarn: true
},
detectBrowserLanguage: false
},

Related

How to show a static error page on invalid route in ojet

How to display an error page for an Oracle Ojet application when someone hits an invalid url? If appController.js is where the main routes are defined, how to use to add the invalid hits?
Thanks!
let navData = [
{ path: '', redirect: 'dashboard' },
{ path:'404',detail: { label: '', iconClass: '' }},
{ path: 'about', detail: { label: 'About', iconClass: 'oj-ux-ico-information-s'}}
{path:/.*/,redirect:404,detail:{ label: '', iconClass: '' }}
];

Datatable Editor's "new" form posts empty values

after one week of search/tests/debugging and headaches... I'm kindly seeking your help on the following problem: Consider the following simple piece of code (I'm focusing on the POST only):
var editor = new $.fn.dataTable.Editor( {
ajax: {
create: {
type: 'POST',
url: '/employees'
},
edit: {
type: 'PUT',
url: 'XXXXXXXX'
},
remove: {
type: 'DELETE',
url: 'XXXXXXXX'
}
},
table: "#example",
fields: [ {
label: "First name:",
name: "first_name"
}, {
label: "Last name:",
name: "last_name"
}, {
label: "Position:"
name: "position"
}
]
} );
$('#example').DataTable( {
dom: "Bfrtip",
ajax: "/employees",
columns: [
{ data: "first_name" },
{ data: "last_name" },
{ data: "position" },
],
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
]
} );
When I submit the form, it posts empty values for the 3 fields! Do I need to serialize Editor's form fields?
I'm using Laravel as PHP MVC The related "#example" datatables displays data correctly, no problem on that.
I just want to use the client side Datatable...
Thanks a lot for your help!
Actually the form is posting values... However I get them as "urlencode" and can't use them in my controller... Will post another question...

Extjs proxy just post dirty fields to server, not all filelds

I have a model:
Ext.define('CrudTest.model.User', {
extend: 'Ext.data.Model',
idProperty: 'Id',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'Name', type: 'string' },
{ name: 'PhoneNumber', type: 'int' },
{ name: 'Address', type: 'string' },
{ name: 'StateId', type: 'int', reference: 'State' },
],
validators: [
{ type: 'presence', field: 'Name', message: 'define name, please' },
{ type: 'length', field: 'PhoneNumber', max: 8, messsage: 'lower than 8 digit' },
],
proxy: {
type: 'ajax',
api: {
create: 'home/new',
read: 'home/users',
update: 'home/Edit',
destroy: 'home/Delete'
},
},
});
and a form that load data to form by loadRecord() and my handler code for submit button is:
var form = this.up('form').getForm();
if (form.isValid()) {
form.getRecord().save();
}
it make a post request through my proxy model good. but the body of request just have dirty(edited) fields. why i don't have other fields?
but in request body i have just dirty fields. why? i know updateRecord() uses getFieldValues([onlyDirty=false]), how can send all fields values?
I use extjs 5
Finally find the problem. Ext.data.writer.Writer has a config property writeAllFields
So i change the proxy to this:
proxy: {
writer:{ writeAllFields:true },
type: 'ajax', //also works with type: 'direct',
api: {
create: 'home/new',
read: 'home/users',
update: 'home/Edit',
destroy: 'home/Delete'
},
You can set crtical: true on the Model to any fields you always want written whether changed or not, e.g.
{ name: 'title', type: 'string', critical: true }

Sencha Touch 2 proxy not firing any requests

I'm trying to just get a list loaded from a proxy that uses rest to get data from the server. I can't figure out what I'm doing wrong, but I don't see any GET requests to /restaurants in Chrome's network call log. Originally I thought maybe the controller wasn't being included, but it's all there and when I add data in the store it populates. This isn't throwing any errors, so I can't debug it. I've gone through every possible tutorial I could find as well as the documentation. Any help or insight is greatly appreciated.
Controller:
Ext.define('Appetize.controller.Restaurants', {
extend: 'Ext.app.Controller',
config: {
models: ['Restaurant'],
views: [
'RestaurantList',
],
refs: {
},
control: { }
}
}
Model:
Ext.define('Appetize.model.Restaurant', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'id'},
{name: 'name'},
{name: 'delivers'},
{name: 'active'}
]
}
});
store:
Ext.define('Appetize.store.Restaurants', {
extend: 'Ext.data.Store',
requires: ['Appetize.model.Restaurant'],
config: {
model: 'Appetize.model.Restaurant',
proxy: {
type: 'rest',
url: '/restaurants',
autoLoad: 'true'
}
}
});
View:
Ext.define('Appetize.view.RestaurantList', {
extend: 'Ext.List',
xtype: 'restaurantListCard',
config: {
iconCls: 'home',
title: 'Restaurants',
id: 'restaurantList',
store: 'Restaurants',
onItemDisclosure: true,
itemTpl: '{name}'
}
});
It turns out I had autoLoad in the wrong place. It shouldn't be within the proxy settings. Instead it should be outside the proxy as part of config.
Ext.define('Appetize.store.Restaurants', {
extend: 'Ext.data.Store',
requires: ['Appetize.model.Restaurant'],
config: {
model: 'Appetize.model.Restaurant',
proxy: {
type: 'rest',
url: '/restaurants',
},
autoLoad: 'true'
}
});

Load another view after login with sencha touch 2.0

I'm having a dumb problem and I would like you to give me a hand.Thanks in advance.
The situatios is as follows: I have 2 wiews (both created with sencha architect 2.0), one for login, and another for general purposes. And I would like to load the second view on successful response when trying to log in, this is, after any successful login. The main problem is that I've tried with Ex.create, Ext.Viewport.add, Ext.Viewport.setActiveItem, but I can't manage to make the second view to appear on screen, the login screen just keeps there and the app does not load the other view. Another thing, I don't have to use a navigation view for this.
Here is the code of my controller, from which I want to load my second view. And as you'll see, I even created a reference of the view, which has autoCreate enabled and has that ID "mainTabPanel":
Ext.define('MyApp.controller.Login', {
extend: 'Ext.app.Controller',
config: {
refs: {
loginButton: {
selector: '#login',
xtype: 'button'
},
username: {
selector: '#user',
xtype: 'textfield'
},
password: {
selector: '#pass',
xtype: 'passwordfield'
},
mainTabPanel: {
selector: '#mainTabPanel',
xtype: 'tabpanel',
autoCreate: true
}
},
control: {
"loginButton": {
tap: 'onLoginButtonTap'
}
}
},
onLoginButtonTap: function(button, e, options) {
Ext.Ajax.request({
url: '../../backend/auth.php',
method: 'POST',
params: {
user: this.getUsername().getValue(),
pass: this.getPassword().getValue()
},
success: function(response) {
var json = Ext.decode(response.responseText);
if (json.type == 'success') {
// LOAD THE DAMN SECOND VIEW HERE!
//var paneltab = Ext.create('MyApp.view.MainTabPanel');
//Ext.Viewport.add(paneltab);
//Ext.Viewport.setActiveItem(this.getMainTabPanel());
} else {
alert(json.value);
}
},
failure: function(response) {
alert('The request failed!');
}
});
}
});
And here is the code of my login view:
Ext.define('MyApp.view.LoginForm', {
extend: 'Ext.form.Panel',
config: {
id: 'loginForm',
ui: 'light',
items: [
{
xtype: 'fieldset',
ui: 'light',
title: 'Log into the system',
items: [
{
xtype: 'textfield',
id: 'user',
label: 'User',
name: 'user'
},
{
xtype: 'passwordfield',
id: 'pass',
label: 'Pass',
name: 'pass'
}
]
},
{
xtype: 'button',
id: 'login',
ui: 'confirm',
text: 'Login'
}
]
}
});
And finally, the code of the view I want to load. This view loads normally if I set it as the Initial View, but does not load when a successful login occurs:
Ext.define('MyApp.view.MainTabPanel', {
extend: 'Ext.tab.Panel',
config: {
id: 'mainTabPanel',
layout: {
animation: 'slide',
type: 'card'
},
items: [
{
xtype: 'container',
layout: {
type: 'vbox'
},
title: 'Tab 1',
iconCls: 'time',
items: [
{
xtype: 'titlebar',
docked: 'top',
title: 'General Report',
items: [
{
xtype: 'button',
iconCls: 'refresh',
iconMask: true,
text: '',
align: 'right'
}
]
},
{
xtype: 'container',
height: 138,
flex: 1,
items: [
{
xtype: 'datepickerfield',
label: 'From',
placeHolder: 'mm/dd/yyyy'
},
{
xtype: 'datepickerfield',
label: 'To',
placeHolder: 'mm/dd/yyyy'
},
{
xtype: 'numberfield',
label: 'Hours'
}
]
},
{
xtype: 'dataview',
ui: 'dark',
itemTpl: [
'<div style="height:50px; background-color: white; margin-bottom: 1px;">',
' <span style="color: #0000FF">{user}</span>',
' <span>{description}</span>',
'</div>'
],
store: 'hoursStore',
flex: 1
}
]
},
{
xtype: 'container',
title: 'Tab 2',
iconCls: 'maps'
},
{
xtype: 'container',
title: 'Tab 3',
iconCls: 'favorites'
}
],
tabBar: {
docked: 'bottom'
}
}
});
Please, I need help... :)
I'm stuck here for like 3 days now and can't figure out what the problem is. Thank you.
Could you post your app.js too?
I'm trying your code here and it load the view as expected. Here is my app.js:
Ext.application({
name: 'MyApp',
requires: [
'Ext.MessageBox'
],
controllers: ['Login'],
views: ['LoginForm','MainTabPanel'],
icon: {
'57': 'resources/icons/Icon.png',
'72': 'resources/icons/Icon~ipad.png',
'114': 'resources/icons/Icon#2x.png',
'144': 'resources/icons/Icon~ipad#2x.png'
},
isIconPrecomposed: true,
startupImage: {
'320x460': 'resources/startup/320x460.jpg',
'640x920': 'resources/startup/640x920.png',
'768x1004': 'resources/startup/768x1004.png',
'748x1024': 'resources/startup/748x1024.png',
'1536x2008': 'resources/startup/1536x2008.png',
'1496x2048': 'resources/startup/1496x2048.png'
},
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
//Ext.Viewport.add(Ext.create('MyApp.view.Main'));
Ext.Viewport.add(Ext.create('MyApp.view.LoginForm'));
},
onUpdated: function() {
Ext.Msg.confirm(
"Application Update",
"This application has just successfully been updated to the latest version. Reload now?",
function(buttonId) {
if (buttonId === 'yes') {
window.location.reload();
}
}
);
}
});
Destroy the login panel, You don't really need it anymore...
success: function(response) {
var json = Ext.decode(response.responseText);
if (json.type == 'success') {
// LOAD THE DAMN SECOND VIEW HERE!
var paneltab = Ext.create('MyApp.view.MainTabPanel');
Ext.getCmp('loginForm').destroy();
Ext.Viewport.add(paneltab);
} else {
alert(json.value);
}
},
There are several problems here:
Your autoCreate rule uses an xtype: 'tabpanel' which will only ever create a vanilla Ext.TabPanel with no items in it. You'd need to assign an xtype attribute to your MyApp.view.MainTabPanel like xtype: 'mainTabPanel' and then use that xtype value in your autoCreate rule.
This then explains why this code won't work since this.getMainTabPanel() will return the wrong object. Simpler would be to just use Ext.Viewport.setActiveItem(paneltab).
In general, you usually don't want assign an id to a view (id: 'mainTabPanel'). Safer to just use an xtype to fetch it. Although you don't need it in this case, avoiding global id's allows you to create multiple instances of a view (or any other class type).

Resources