[{"_path":"/blog/variables-and-scopes-in-js","_draft":false,"_partial":false,"_empty":false,"title":"Variables & Scopes in JS.","description":"New to JavaScript? Let me help you to dive in.","excerpt":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This article will overview variables and scopes in JavaScript and other related things."}]},{"type":"element","tag":"h2","props":{"id":"global-scope"},"children":[{"type":"text","value":"Global Scope."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's declare "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" variables in our JS file.\nIf variables are not in the function, like in the example below, they become a part of Global Scope."}]},{"type":"element","tag":"code","props":{"code":"var a = 10;\nlet b = 10;\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"var a = 10;\nlet b = 10;\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is bad for a few reasons."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reason one: a lifetime of variables in Global Scope is infinite until a user closes the tab in the browser. If you store a lot of data in Global Scope, it may affect performance and memory consumption."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reason two: declaring a variable in Global Scope without a good reason is an efficient way to write poor code,\nbecause the code written this way is harder to support, test, and understand."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reason three (for "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" only): If you are not using 'strict mode' in your JS file, "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" in Global Scope will become the property of the window object. With this, you can accidentally overwrite the window’s object variable or function, and that would lead only to pain, fear, and bugs."}]},{"type":"element","tag":"h2","props":{"id":"function-scope"},"children":[{"type":"text","value":"Function Scope. "}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" variable behaves differently than "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" when declared in the function."}]},{"type":"element","tag":"code","props":{"code":"function outer() {\n var x = 12;\n\n function inner() {\n console.log(x); // 12\n }\n\n if (2 + 2 == 4) {\n console.log(x); // 12\n }\n\n inner();\n}\n\nouter();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function outer() {\n var x = 12;\n\n function inner() {\n console.log(x); // 12\n }\n\n if (2 + 2 == 4) {\n console.log(x); // 12\n }\n\n inner();\n}\n\nouter();\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As you can see, we can access the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable anywhere in the function where it was declared. Independent of nesting level. In that case, the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable lifetime ends only with a closing bracket of function where it was declared."}]},{"type":"element","tag":"h2","props":{"id":"block-scope"},"children":[{"type":"text","value":"Block Scope."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Opposite of Function Scope is the Block Scope. When you declare a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" variable, its lifetime ends with a closing bracket of its block."}]},{"type":"element","tag":"code","props":{"code":"{\n let x = 10;\n} // lifetime of x ends.\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"{\n let x = 10;\n} // lifetime of x ends.\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Also, you can access the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable only from inside the block where it was declared."}]},{"type":"element","tag":"code","props":{"code":"function func() {\n if (2 + 2 == 4) {\n let x = 10;\n console.log(x); // 10\n }\n\n console.log(x); // Uncaught ReferenceError: x is not defined\n}\n\nfunc();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function func() {\n if (2 + 2 == 4) {\n let x = 10;\n console.log(x); // 10\n }\n\n console.log(x); // Uncaught ReferenceError: x is not defined\n}\n\nfunc();\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"const-variable"},"children":[{"type":"text","value":"const Variable. "}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" is the same as "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":", but you can't change the variable value after initialization."}]},{"type":"element","tag":"code","props":{"code":"const x = 10;\n\nx = 5; // Uncaught TypeError: Assignment to constant variable.\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const x = 10;\n\nx = 5; // Uncaught TypeError: Assignment to constant variable.\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_03","src":"/blog/vars_scopes_js/meme_03.webp"},"children":[]}]},{"type":"element","tag":"h2","props":{"id":"temporal-dead-zone-tdz"},"children":[{"type":"text","value":"Temporal Dead Zone (TDZ)"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And this is where all the fun begins."}]},{"type":"element","tag":"code","props":{"code":"function simpleFunc() {\n console.log(x); // Reference error\n\n let x = 10;\n}\n\nsimpleFunc();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function simpleFunc() {\n console.log(x); // Reference error\n\n let x = 10;\n}\n\nsimpleFunc();\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And what is going to happen if we change "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":"?"}]},{"type":"element","tag":"code","props":{"code":"function simpleFunc() {\n console.log(x); // undefined\n\n var x = 10;\n}\n\nsimpleFunc();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function simpleFunc() {\n console.log(x); // undefined\n\n var x = 10;\n}\n\nsimpleFunc();\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Interesting. To understand this, we need to talk about hoisting. \nHoisting is JavaScript's mechanism that moves variables and function declarations to the top of their scope. And if you try to use a variable before it was declared in the code, you will get an "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":" value or the reference error depending on which variable you try to access "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" or "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"JavaScript binds a variable or a function to its scope that way. \nNote that only variable declaration pops up, not the variable initialization!\nSo what is TDZ? \nTDZ is the term to describe a state when a variable/function is unreachable. Like in the example above, we can't access the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable before it was declared because "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"console.log(x)"}]},{"type":"text","value":" is in Temporal Dead Zone. \nAlso, "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":"/"},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" behaviors are different in TDZ. In the case of "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":"/"},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":", you would get a Reference Error while trying to access a variable in TDZ. In the case of var, you get "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":", which may lead to problems."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_1","src":"/blog/vars_scopes_js/meme_01.jpeg"},"children":[]}]},{"type":"element","tag":"h2","props":{"id":"arguments-in-functions--lexical-environment"},"children":[{"type":"text","value":"Arguments in functions & Lexical Environment."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Arguments that you pass into the function are attached to the scope of that function."}]},{"type":"element","tag":"code","props":{"code":"function func(x) {\n console.log(x); // undefined\n}\nvar x = 'I'm outside the function!';\nfunc();\n\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function func(x) {\n console.log(x); // undefined\n}\nvar x = 'I'm outside the function!';\nfunc();\n\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Wow! We get "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":" here! The reason is we don't pass a value to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"func()"}]},{"type":"text","value":" when calling it, but in the function declaration, func(x) has x as the argument. So when JavaScript calls "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"console.log(x)"}]},{"type":"text","value":", it finds the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable in the function's scope. But since we don't pass any value as an argument, the value of x is "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's change the example a bit."}]},{"type":"element","tag":"code","props":{"code":"function func(a) {\n console.log(x); // I'm outside the function!\n}\nvar x = 'I'm outside the function!';\nfunc();\n\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function func(a) {\n console.log(x); // I'm outside the function!\n}\nvar x = 'I'm outside the function!';\nfunc();\n\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So in this example, JavaScript does the next thing, it searches for the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable in the function's scope and doesn't find it. Then JavaScript moves to the outer scope and searches for the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable there, and now JavaScript finds it and passes the value of the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" to the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"console.log()"}]},{"type":"text","value":";"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When JavaScript looks for a variable, it starts from the local scope and moves to outer scopes until it reaches the Global Scope. If JavaScript did not find a variable in Global Scope, you would get a Reference Error."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This mechanism is called the Lexical Environment. To easily understand how it works, imagine when you create a function and declare a variable in it. JavaScript creates the object for this function, containing all functions, variables, and ref to an outer object. When you try to access a variable and JavaScript does not find it in the current Lexical Environment, the JavaScript goes to the outer Lexical Environment by the ref."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This diagram shows Lexical Environment conditionally but can help you understand this."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_03","src":"/blog/vars_scopes_js/diagram.png"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this diagram, coffee and name are variables in functions lexical environment, and ref leads to outer Lexical environment. Ref of Global Scope is "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"null"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"closures"},"children":[{"type":"text","value":"Closures."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Imagine we want to create a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" that counts how much ice latte we have drunk.  But there is one condition, we want to make the counter variable accessible only within the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"function"}]},{"type":"text","value":"."}]},{"type":"element","tag":"code","props":{"code":"function drinkLatte() {\n let counter = 0;\n return ++counter;\n}\n\nconsole.log(drinkLatte()); // 1\nconsole.log(drinkLatte()); // 1\nconsole.log(drinkLatte()); // 1\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function drinkLatte() {\n let counter = 0;\n return ++counter;\n}\n\nconsole.log(drinkLatte()); // 1\nconsole.log(drinkLatte()); // 1\nconsole.log(drinkLatte()); // 1\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Have you noticed the issue? Is the counter variable accessible only with the function? Yes. Does this code work properly? No.\nEvery time we call "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"drinkLatte()"}]},{"type":"text","value":", it will return 1. It works because the counter’s variable lifetime ends with the function’s close bracket. So in this example, we create a counter variable three times with a value of 0, then increment the counter to a value of 1 and return. We need a mechanism that can save the state of variables.\nClosures can help us with that. Here is another example of using closures."}]},{"type":"element","tag":"code","props":{"code":"function getLatte() {\n let counter = 0;\n return function drinkLatte() {\n return ++counter;\n };\n}\n\nconst latte = getLatte();\n\nconsole.log(latte()); // 1\nconsole.log(latte()); // 2\nconsole.log(latte()); // 3\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"function getLatte() {\n let counter = 0;\n return function drinkLatte() {\n return ++counter;\n };\n}\n\nconst latte = getLatte();\n\nconsole.log(latte()); // 1\nconsole.log(latte()); // 2\nconsole.log(latte()); // 3\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It works! We created a new function named "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getLatte"}]},{"type":"text","value":" which wrapped our previous function. The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getLatte"}]},{"type":"text","value":" function has a counter variable declared in it, and it returns the drinkLatte function, which increments the counter variable from the outer function.\nThen we initialize the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"latte"}]},{"type":"text","value":" variable with returned function, so now we can call the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"text","value":" function from that variable."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"With Closures, we can expand the lifetime of a variable and use it in inner functions."}]},{"type":"element","tag":"h2","props":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_02","src":"/blog/vars_scopes_js/meme_02.jpeg"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Avoid using Global Variables without good reason.\nUse "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" & "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" instead of "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" as it is much safer.\nBe aware of TDZ and keep in mind how Lexical Environment works."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"That’s all! Thanks for reading. If you liked the article, you could help Ukraine. Even $1 would help."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Come Back Alive Fund: "},{"type":"element","tag":"a","props":{"href":"https://savelife.in.ua/en/donate-en/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"https://savelife.in.ua/en/donate-en/"}]},{"type":"text","value":"."}]}]},"topic":"Variables & Scopes in JavaScript","createdAt":1660075676825,"category":"Web development","image":"/blog/vars_scopes_js/js-logo.png","head":{"image":"/blog/vars_scopes_js/js-logo.png"},"author":{"name":"Nikita Tovstyga","bio":"Front-end Developer","img":"/blog/authors/nikita.webp"},"tags":["JavaScript"],"body":{"type":"root","children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This article will overview variables and scopes in JavaScript and other related things."}]},{"type":"element","tag":"h2","props":{"id":"global-scope"},"children":[{"type":"text","value":"Global Scope."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's declare "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" variables in our JS file.\nIf variables are not in the function, like in the example below, they become a part of Global Scope."}]},{"type":"element","tag":"code","props":{"code":"var a = 10;\nlet b = 10;\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"var"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" a "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"let"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" b "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is bad for a few reasons."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reason one: a lifetime of variables in Global Scope is infinite until a user closes the tab in the browser. If you store a lot of data in Global Scope, it may affect performance and memory consumption."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reason two: declaring a variable in Global Scope without a good reason is an efficient way to write poor code,\nbecause the code written this way is harder to support, test, and understand."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Reason three (for "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" only): If you are not using 'strict mode' in your JS file, "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" in Global Scope will become the property of the window object. With this, you can accidentally overwrite the window’s object variable or function, and that would lead only to pain, fear, and bugs."}]},{"type":"element","tag":"h2","props":{"id":"function-scope"},"children":[{"type":"text","value":"Function Scope. "}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" variable behaves differently than "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" when declared in the function."}]},{"type":"element","tag":"code","props":{"code":"function outer() {\n var x = 12;\n\n function inner() {\n console.log(x); // 12\n }\n\n if (2 + 2 == 4) {\n console.log(x); // 12\n }\n\n inner();\n}\n\nouter();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"outer"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"var"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"12"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"inner"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 12"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" }"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"+"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"4"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":") {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 12"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" }"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"inner"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"outer"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As you can see, we can access the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable anywhere in the function where it was declared. Independent of nesting level. In that case, the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable lifetime ends only with a closing bracket of function where it was declared."}]},{"type":"element","tag":"h2","props":{"id":"block-scope"},"children":[{"type":"text","value":"Block Scope."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Opposite of Function Scope is the Block Scope. When you declare a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" variable, its lifetime ends with a closing bracket of its block."}]},{"type":"element","tag":"code","props":{"code":"{\n let x = 10;\n} // lifetime of x ends.\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"{"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"let"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"} "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// lifetime of x ends."}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Also, you can access the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable only from inside the block where it was declared."}]},{"type":"element","tag":"code","props":{"code":"function func() {\n if (2 + 2 == 4) {\n let x = 10;\n console.log(x); // 10\n }\n\n console.log(x); // Uncaught ReferenceError: x is not defined\n}\n\nfunc();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"func"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"if"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"+"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"4"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":") {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"let"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 10"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" }"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// Uncaught ReferenceError: x is not defined"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"func"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"const-variable"},"children":[{"type":"text","value":"const Variable. "}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" is the same as "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":", but you can't change the variable value after initialization."}]},{"type":"element","tag":"code","props":{"code":"const x = 10;\n\nx = 5; // Uncaught TypeError: Assignment to constant variable.\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"x"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"5"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"; "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// Uncaught TypeError: Assignment to constant variable."}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_03","src":"/blog/vars_scopes_js/meme_03.webp"},"children":[]}]},{"type":"element","tag":"h2","props":{"id":"temporal-dead-zone-tdz"},"children":[{"type":"text","value":"Temporal Dead Zone (TDZ)"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And this is where all the fun begins."}]},{"type":"element","tag":"code","props":{"code":"function simpleFunc() {\n console.log(x); // Reference error\n\n let x = 10;\n}\n\nsimpleFunc();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"simpleFunc"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// Reference error"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"let"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"simpleFunc"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And what is going to happen if we change "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":"?"}]},{"type":"element","tag":"code","props":{"code":"function simpleFunc() {\n console.log(x); // undefined\n\n var x = 10;\n}\n\nsimpleFunc();\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"simpleFunc"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// undefined"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"var"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"10"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"simpleFunc"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Interesting. To understand this, we need to talk about hoisting. \nHoisting is JavaScript's mechanism that moves variables and function declarations to the top of their scope. And if you try to use a variable before it was declared in the code, you will get an "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":" value or the reference error depending on which variable you try to access "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" or "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"JavaScript binds a variable or a function to its scope that way. \nNote that only variable declaration pops up, not the variable initialization!\nSo what is TDZ? \nTDZ is the term to describe a state when a variable/function is unreachable. Like in the example above, we can't access the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable before it was declared because "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"console.log(x)"}]},{"type":"text","value":" is in Temporal Dead Zone. \nAlso, "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":"/"},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" behaviors are different in TDZ. In the case of "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":"/"},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":", you would get a Reference Error while trying to access a variable in TDZ. In the case of var, you get "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":", which may lead to problems."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_1","src":"/blog/vars_scopes_js/meme_01.jpeg"},"children":[]}]},{"type":"element","tag":"h2","props":{"id":"arguments-in-functions--lexical-environment"},"children":[{"type":"text","value":"Arguments in functions & Lexical Environment."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Arguments that you pass into the function are attached to the scope of that function."}]},{"type":"element","tag":"code","props":{"code":"function func(x) {\n console.log(x); // undefined\n}\nvar x = 'I'm outside the function!';\nfunc();\n\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"func"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"x"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":") {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// undefined"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"var"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'I'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"m outside the "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"!';"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"func"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Wow! We get "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":" here! The reason is we don't pass a value to "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"func()"}]},{"type":"text","value":" when calling it, but in the function declaration, func(x) has x as the argument. So when JavaScript calls "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"console.log(x)"}]},{"type":"text","value":", it finds the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable in the function's scope. But since we don't pass any value as an argument, the value of x is "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"undefined"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's change the example a bit."}]},{"type":"element","tag":"code","props":{"code":"function func(a) {\n console.log(x); // I'm outside the function!\n}\nvar x = 'I'm outside the function!';\nfunc();\n\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"func"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":") {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(x); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// I'm outside the function!"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"var"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" x "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'I'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"m outside the "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"!';"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"func"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So in this example, JavaScript does the next thing, it searches for the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable in the function's scope and doesn't find it. Then JavaScript moves to the outer scope and searches for the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" variable there, and now JavaScript finds it and passes the value of the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"x"}]},{"type":"text","value":" to the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"console.log()"}]},{"type":"text","value":";"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"When JavaScript looks for a variable, it starts from the local scope and moves to outer scopes until it reaches the Global Scope. If JavaScript did not find a variable in Global Scope, you would get a Reference Error."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This mechanism is called the Lexical Environment. To easily understand how it works, imagine when you create a function and declare a variable in it. JavaScript creates the object for this function, containing all functions, variables, and ref to an outer object. When you try to access a variable and JavaScript does not find it in the current Lexical Environment, the JavaScript goes to the outer Lexical Environment by the ref."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This diagram shows Lexical Environment conditionally but can help you understand this."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_03","src":"/blog/vars_scopes_js/diagram.png"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this diagram, coffee and name are variables in functions lexical environment, and ref leads to outer Lexical environment. Ref of Global Scope is "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"null"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h2","props":{"id":"closures"},"children":[{"type":"text","value":"Closures."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Imagine we want to create a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" that counts how much ice latte we have drunk.  But there is one condition, we want to make the counter variable accessible only within the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"function"}]},{"type":"text","value":"."}]},{"type":"element","tag":"code","props":{"code":"function drinkLatte() {\n let counter = 0;\n return ++counter;\n}\n\nconsole.log(drinkLatte()); // 1\nconsole.log(drinkLatte()); // 1\nconsole.log(drinkLatte()); // 1\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"let"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" counter "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"0"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"++"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"counter;"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 1"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 1"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 1"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Have you noticed the issue? Is the counter variable accessible only with the function? Yes. Does this code work properly? No.\nEvery time we call "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"drinkLatte()"}]},{"type":"text","value":", it will return 1. It works because the counter’s variable lifetime ends with the function’s close bracket. So in this example, we create a counter variable three times with a value of 0, then increment the counter to a value of 1 and return. We need a mechanism that can save the state of variables.\nClosures can help us with that. Here is another example of using closures."}]},{"type":"element","tag":"code","props":{"code":"function getLatte() {\n let counter = 0;\n return function drinkLatte() {\n return ++counter;\n };\n}\n\nconst latte = getLatte();\n\nconsole.log(latte()); // 1\nconsole.log(latte()); // 2\nconsole.log(latte()); // 3\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"getLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"let"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" counter "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"0"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"++"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"counter;"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" };"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"latte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"getLatte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"latte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 1"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"latte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 2"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"latte"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// 3"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It works! We created a new function named "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getLatte"}]},{"type":"text","value":" which wrapped our previous function. The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getLatte"}]},{"type":"text","value":" function has a counter variable declared in it, and it returns the drinkLatte function, which increments the counter variable from the outer function.\nThen we initialize the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"latte"}]},{"type":"text","value":" variable with returned function, so now we can call the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"drinkLatte"}]},{"type":"text","value":" function from that variable."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"With Closures, we can expand the lifetime of a variable and use it in inner functions."}]},{"type":"element","tag":"h2","props":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"article-img","props":{"alt":"meme_02","src":"/blog/vars_scopes_js/meme_02.jpeg"},"children":[]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Avoid using Global Variables without good reason.\nUse "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" & "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" instead of "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"var"}]},{"type":"text","value":" as it is much safer.\nBe aware of TDZ and keep in mind how Lexical Environment works."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"That’s all! Thanks for reading. If you liked the article, you could help Ukraine. Even $1 would help."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Come Back Alive Fund: "},{"type":"element","tag":"a","props":{"href":"https://savelife.in.ua/en/donate-en/","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"https://savelife.in.ua/en/donate-en/"}]},{"type":"text","value":"."}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"global-scope","depth":2,"text":"Global Scope."},{"id":"function-scope","depth":2,"text":"Function Scope. "},{"id":"block-scope","depth":2,"text":"Block Scope."},{"id":"const-variable","depth":2,"text":"const Variable. "},{"id":"temporal-dead-zone-tdz","depth":2,"text":"Temporal Dead Zone (TDZ)"},{"id":"arguments-in-functions--lexical-environment","depth":2,"text":"Arguments in functions & Lexical Environment."},{"id":"closures","depth":2,"text":"Closures."},{"id":"conclusion","depth":2,"text":"Conclusion."}]}},"_type":"markdown","_id":"content:blog:variables-and-scopes-in-JS.md","_source":"content","_file":"blog/variables-and-scopes-in-JS.md","_extension":"md"},{"_path":"/blog/nuxt3-nuxtcontent2-meta-tags","_draft":false,"_partial":false,"_empty":false,"title":"Adding Meta tags in Nuxt 3 and Nuxt Content 2","description":"While Nuxt v3 is still not released (RC) and docs are missing some pages, it doesn't stop enthusiasts from using it.","excerpt":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"adding-meta-tags-in-nuxt-3-and-nuxt-content-2"},"children":[{"type":"text","value":"Adding Meta tags in Nuxt 3 and Nuxt Content 2"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a developer, I love to build websites. I enjoy the process itself and the results I see.\nAs a product owner, I want to make the website noticeable in search engines and social media. To make that happen, you need to work on your website Meta tags. Adding Meta, Open Graph, and Twitter Meta tags are the same in Nuxt."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for now, Nuxt 3 is still not released, so that things may change in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are several ways to set the Meta tags in Nuxt 3. Not all of them are dynamic:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"nuxt.config.ts (dynamic ❌)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"useHead composable (dynamic ✅)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Meta components (dynamic ✅)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"useMeta (deprecated)"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's see how you can use them in your code."}]},{"type":"element","tag":"h3","props":{"id":"nuxtconfigts"},"children":[{"type":"text","value":"Nuxt.config.ts"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can set the META tags in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":". I believe this is a good place for the tags\nthat rarely / never change."}]},{"type":"element","tag":"code","props":{"code":"export default defineNuxtConfig({\n // Global page headers: https://go.nuxtjs.dev/config-head\n app: {\n head: {\n htmlAttrs: {\n lang: 'en'\n },\n meta: [\n {name: 'viewport', content: 'width=device-width, initial-scale=1'},\n {property: 'og:site_name', content: 'XDEVS.PRO'},\n {property: 'og:image', content: 'https://xdevs.pro/ogXDEVS.png'},\n {property: 'og:url', content: 'https://xdevs.pro/'},\n {property: \"og:type\", content: \"website\"},\n ],\n link: [\n {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}\n ]\n },\n },\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export default defineNuxtConfig({\n // Global page headers: https://go.nuxtjs.dev/config-head\n app: {\n head: {\n htmlAttrs: {\n lang: 'en'\n },\n meta: [\n {name: 'viewport', content: 'width=device-width, initial-scale=1'},\n {property: 'og:site_name', content: 'XDEVS.PRO'},\n {property: 'og:image', content: 'https://xdevs.pro/ogXDEVS.png'},\n {property: 'og:url', content: 'https://xdevs.pro/'},\n {property: \"og:type\", content: \"website\"},\n ],\n link: [\n {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}\n ]\n },\n },\n})\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"usehead-composable"},"children":[{"type":"text","value":"useHead composable"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It can be used to set constant Meta tags, or you can use it in combination with "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useRoute"}]},{"type":"text","value":", which adds a bit of flexibility. "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" can be used both globally and on per page basis."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In your "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"app.vue"}]},{"type":"text","value":", you can set global Meta tags in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" composable:"}]},{"type":"element","tag":"code","props":{"code":"\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Any other page component, e.g., "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"blog/index.vue"}]}]},{"type":"element","tag":"code","props":{"code":"// You can override the global title \n// that was set in app.vue like this\nuseHead({ \n title: 'XDEVS Team Blog – our latest articles 📚', \n}) \n\n// it won't have direct access to your meta tags\ndefinePageMeta({ \n layout: 'blog', \n ogType: 'OgType',\n otherArgs: youWantToPass \n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"// You can override the global title \n// that was set in app.vue like this\nuseHead({ \n title: 'XDEVS Team Blog – our latest articles 📚', \n}) \n\n// it won't have direct access to your meta tags\ndefinePageMeta({ \n layout: 'blog', \n ogType: 'OgType',\n otherArgs: youWantToPass \n})\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"usehead-title-templates"},"children":[{"type":"text","value":"useHead Title Templates"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, something we can use to set the page title dynamically. Unfortunately, it works only with the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" tag."}]},{"type":"element","tag":"code","props":{"code":"// in your app.vue, add the following.\nconst route = useRoute()\n\nuseHead({\n // route.meta.title is is defined in definePageMeta({}) in another page component\n titleTemplate: (titleChunk) => {\n return titleChunk || route.meta.title || 'Site Default Title'\n },\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"// in your app.vue, add the following.\nconst route = useRoute()\n\nuseHead({\n // route.meta.title is is defined in definePageMeta({}) in another page component\n titleTemplate: (titleChunk) => {\n return titleChunk || route.meta.title || 'Site Default Title'\n },\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now you can set the title using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" or "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" on any other page of your website."}]},{"type":"element","tag":"code","props":{"code":"useHead({\n title: 'Some other page title.',\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"useHead({\n title: 'Some other page title.',\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"or"}]},{"type":"element","tag":"code","props":{"code":"definePageMeta({\n title: 'Any other page title.',\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"definePageMeta({\n title: 'Any other page title.',\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In case no title is set, the default title will be used."}]},{"type":"element","tag":"h3","props":{"id":"definepagemeta"},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" is extracted at build time via a macro, so it can't be set dynamically.\nIt extends "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"route.meta"}]},{"type":"text","value":" with any non-dynamic information you pass. It's important to notice that you can't set Meta tags using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" without using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" composable."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"page1.vue"}]}]},{"type":"element","tag":"code","props":{"code":"definePageMeta({\n someInformation: 'You may need elsewhere available at a build time.'\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"definePageMeta({\n someInformation: 'You may need elsewhere available at a build time.'\n})\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"app.vue"}]}]},{"type":"element","tag":"code","props":{"code":"const route = useRoute()\n\nconsole.log(route.meta.someInformation)\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"const route = useRoute()\n\nconsole.log(route.meta.someInformation)\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"meta-components"},"children":[{"type":"text","value":"Meta components"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may find the Meta component a more flexible and valuable solution to set Meta tags."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt provides "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":""}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Base>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Script>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Style>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Meta>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Link>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Body>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Html>"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Head>"}]},{"type":"text","value":" components so that you can interact directly with your metadata within your component's template."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"They can be used with any dynamic data like a regular Nuxt component."}]},{"type":"element","tag":"code","props":{"code":"<template>\n <div>\n <Head>\n <Meta property=\"og:title\" content=\"XDEVS – Top Software Engineers for your needs ❤️‍🔥\"/>\n <Meta property=\"og:description\" content=\"Web / mobile app development and consulting across different cycles of your product life.\" />\n <Meta name=\"description\" :content=\"pageDescriptionRef\" />\n </Head>\n </div>\n</template>\n","language":"html"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"<template>\n <div>\n <Head>\n <Meta property=\"og:title\" content=\"XDEVS – Top Software Engineers for your needs ❤️‍🔥\"/>\n <Meta property=\"og:description\" content=\"Web / mobile app development and consulting across different cycles of your product life.\" />\n <Meta name=\"description\" :content=\"pageDescriptionRef\" />\n </Head>\n </div>\n</template>\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"how-do-i-set-meta-tags-with-nuxt-content-v2"},"children":[{"type":"text","value":"How do I set META tags with Nuxt Content v2?"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Managing Meta tags in Nuxt Content is made very easy."}]},{"type":"element","tag":"h3","props":{"id":"front-matter"},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Front-matter"}]},{"type":"text","value":":"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Front-matter"}]},{"type":"text","value":" is a convention of Markdown-based CMS to provide meta-data to pages, like description or title. In Nuxt Content, the front-matter uses the YAML syntax with "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"key: value"}]},{"type":"text","value":" pairs."}]}]},{"type":"element","tag":"code","props":{"code":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\n---\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\n---\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"usecontenthead"},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"useContentHead()"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is basically the same as "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead()"}]},{"type":"text","value":" that we talked about earlier."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"useContentHead()"}]},{"type":"text","value":" is a composable providing a binding between your content data and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead()"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"code","props":{"code":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\nimage:\n src: '/assets/image.jpg'\n alt: 'An image showcasing My Page.'\n width: 400\n height: 300\nhead:\n meta:\n - name: 'keywords'\n content: 'nuxt, vue, content'\n - name: 'robots'\n content: 'index, follow'\n - name: 'author'\n content: 'NuxtLabs'\n---\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\nimage:\n src: '/assets/image.jpg'\n alt: 'An image showcasing My Page.'\n width: 400\n height: 300\nhead:\n meta:\n - name: 'keywords'\n content: 'nuxt, vue, content'\n - name: 'robots'\n content: 'index, follow'\n - name: 'author'\n content: 'NuxtLabs'\n---\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Moreover, you can dynamically use "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"Nuxt Meta components"}]},{"type":"text","value":" to set Meta tags on the article page. To see a real-world example of setting Meta tags in the Nuxt 3 project, you can check our "},{"type":"element","tag":"a","props":{"href":"https://github.com/XDEVS-PRO/XDEVS-website","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"repo"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There is definitely more than one way to set Meta tags in the Nuxt 3 framework. Is it bad or good? It's up to you. Having the possibility to make the same thing in multiple ways may be confusing for some people, including myself, but as Nuxt 3 is getting released, I believe we will get more clarification regarding adding Meta tags :)"}]}]},"topic":"Nuxt 3 - Nuxt Content 2","createdAt":1658865733050,"category":"Web development","image":"/blog/nuxt3_seo_tags/nuxt-nuxt-content.png","head":{"image":"/blog/nuxt3_seo_tags/nuxt-nuxt-content.png"},"alt":"Managing SEO tags in Nuxt3 and Nuxt Content v2.","author":{"name":"Xander Pokhylenko","bio":"Full-stack Developer","img":"/blog/authors/xander.webp"},"tags":["Nuxt","Nuxt Content"],"body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"adding-meta-tags-in-nuxt-3-and-nuxt-content-2"},"children":[{"type":"text","value":"Adding Meta tags in Nuxt 3 and Nuxt Content 2"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a developer, I love to build websites. I enjoy the process itself and the results I see.\nAs a product owner, I want to make the website noticeable in search engines and social media. To make that happen, you need to work on your website Meta tags. Adding Meta, Open Graph, and Twitter Meta tags are the same in Nuxt."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As for now, Nuxt 3 is still not released, so that things may change in the future."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are several ways to set the Meta tags in Nuxt 3. Not all of them are dynamic:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"nuxt.config.ts (dynamic ❌)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"useHead composable (dynamic ✅)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Meta components (dynamic ✅)"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"useMeta (deprecated)"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's see how you can use them in your code."}]},{"type":"element","tag":"h3","props":{"id":"nuxtconfigts"},"children":[{"type":"text","value":"Nuxt.config.ts"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You can set the META tags in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"nuxt.config.ts"}]},{"type":"text","value":". I believe this is a good place for the tags\nthat rarely / never change."}]},{"type":"element","tag":"code","props":{"code":"export default defineNuxtConfig({\n // Global page headers: https://go.nuxtjs.dev/config-head\n app: {\n head: {\n htmlAttrs: {\n lang: 'en'\n },\n meta: [\n {name: 'viewport', content: 'width=device-width, initial-scale=1'},\n {property: 'og:site_name', content: 'XDEVS.PRO'},\n {property: 'og:image', content: 'https://xdevs.pro/ogXDEVS.png'},\n {property: 'og:url', content: 'https://xdevs.pro/'},\n {property: \"og:type\", content: \"website\"},\n ],\n link: [\n {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}\n ]\n },\n },\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"default"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"defineNuxtConfig"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// Global page headers: https://go.nuxtjs.dev/config-head"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"app: {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" head: {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" htmlAttrs: {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" lang: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'en'"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" },"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" meta: ["}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {name: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'viewport'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'width=device-width, initial-scale=1'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"},"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {property: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'og:site_name'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'XDEVS.PRO'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"},"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {property: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'og:image'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'https://xdevs.pro/ogXDEVS.png'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"},"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {property: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'og:url'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'https://xdevs.pro/'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"},"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {property: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"og:type\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"website\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"},"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ],"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" link: ["}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {rel: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'icon'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", type: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'image/x-icon'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", href: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'/favicon.ico'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ]"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" },"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" }"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"})"}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"usehead-composable"},"children":[{"type":"text","value":"useHead composable"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It can be used to set constant Meta tags, or you can use it in combination with "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useRoute"}]},{"type":"text","value":", which adds a bit of flexibility. "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" can be used both globally and on per page basis."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In your "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"app.vue"}]},{"type":"text","value":", you can set global Meta tags in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" composable:"}]},{"type":"element","tag":"code","props":{"code":"<script setup lang=\"ts\">\nconst route = useRoute()\n\nuseHead({\n title: 'My App',\n // or, instead:\n // titleTemplate: (title) => `My App - ${title}`,\n viewport: 'width=device-width, initial-scale=1, maximum-scale=1',\n charset: 'utf-8',\n meta: [\n {property: 'og:url', content: computed(() => `https://xdevs.pro${route.path}`)},\n // extract og:type from route.meta.ogType which is defined in definePageMeta({}) on any other page\n {property: 'og:type', content: computed(() => route.meta.ogType || 'website')}\n ],\n})\n</script>\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"script setup lang"}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"ts\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"route"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useRoute"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useHead"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'My App'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// or, instead:"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// titleTemplate: (title) => `My App - ${title}`,"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" viewport: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'width=device-width, initial-scale=1, maximum-scale=1'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" charset: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'utf-8'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" meta: ["}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {property: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'og:url'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"computed"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(() "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"`https://xdevs.pro${"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"route"}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"path"}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"}`"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":")},"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// extract og:type from route.meta.ogType which is defined in definePageMeta({}) on any other page"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {property: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'og:type'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", content: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"computed"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(() "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" route.meta.ogType "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"||"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'website'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":")}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ],"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"})"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"script"}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":">"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Any other page component, e.g., "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"blog/index.vue"}]}]},{"type":"element","tag":"code","props":{"code":"// You can override the global title \n// that was set in app.vue like this\nuseHead({ \n title: 'XDEVS Team Blog – our latest articles 📚', \n}) \n\n// it won't have direct access to your meta tags\ndefinePageMeta({ \n layout: 'blog', \n ogType: 'OgType',\n otherArgs: youWantToPass \n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// You can override the global title "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// that was set in app.vue like this"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useHead"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'XDEVS Team Blog – our latest articles 📚'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}) "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// it won't have direct access to your meta tags"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" layout: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'blog'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ogType: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'OgType'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" otherArgs: youWantToPass "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"})"}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"usehead-title-templates"},"children":[{"type":"text","value":"useHead Title Templates"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Finally, something we can use to set the page title dynamically. Unfortunately, it works only with the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" tag."}]},{"type":"element","tag":"code","props":{"code":"// in your app.vue, add the following.\nconst route = useRoute()\n\nuseHead({\n // route.meta.title is is defined in definePageMeta({}) in another page component\n titleTemplate: (titleChunk) => {\n return titleChunk || route.meta.title || 'Site Default Title'\n },\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// in your app.vue, add the following."}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"route"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useRoute"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useHead"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// route.meta.title is is defined in definePageMeta({}) in another page component"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"titleTemplate"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":": ("}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"titleChunk"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" titleChunk "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"||"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" route.meta.title "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"||"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'Site Default Title'"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" },"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"})"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now you can set the title using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" or "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" on any other page of your website."}]},{"type":"element","tag":"code","props":{"code":"useHead({\n title: 'Some other page title.',\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useHead"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'Some other page title.'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"})"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"or"}]},{"type":"element","tag":"code","props":{"code":"definePageMeta({\n title: 'Any other page title.',\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" title: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'Any other page title.'"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"})"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In case no title is set, the default title will be used."}]},{"type":"element","tag":"h3","props":{"id":"definepagemeta"},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" is extracted at build time via a macro, so it can't be set dynamically.\nIt extends "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"route.meta"}]},{"type":"text","value":" with any non-dynamic information you pass. It's important to notice that you can't set Meta tags using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"text","value":" without using "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead"}]},{"type":"text","value":" composable."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"page1.vue"}]}]},{"type":"element","tag":"code","props":{"code":"definePageMeta({\n someInformation: 'You may need elsewhere available at a build time.'\n})\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"definePageMeta"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"({"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" someInformation: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"'You may need elsewhere available at a build time.'"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"})"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"app.vue"}]}]},{"type":"element","tag":"code","props":{"code":"const route = useRoute()\n\nconsole.log(route.meta.someInformation)\n","language":"ts"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"route"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useRoute"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"()"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"console."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"log"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(route.meta.someInformation)"}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"meta-components"},"children":[{"type":"text","value":"Meta components"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"You may find the Meta component a more flexible and valuable solution to set Meta tags."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nuxt provides "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Title>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Base>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Script>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Style>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Meta>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Link>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Body>"}]},{"type":"text","value":", "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Html>"}]},{"type":"text","value":" and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Head>"}]},{"type":"text","value":" components so that you can interact directly with your metadata within your component's template."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"They can be used with any dynamic data like a regular Nuxt component."}]},{"type":"element","tag":"code","props":{"code":"<template>\n <div>\n <Head>\n <Meta property=\"og:title\" content=\"XDEVS – Top Software Engineers for your needs ❤️‍🔥\"/>\n <Meta property=\"og:description\" content=\"Web / mobile app development and consulting across different cycles of your product life.\" />\n <Meta name=\"description\" :content=\"pageDescriptionRef\" />\n </Head>\n </div>\n</template>\n","language":"html"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"Head"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"Meta"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"property"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"og:title\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"content"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"XDEVS – Top Software Engineers for your needs ❤️‍🔥\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"/>"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"Meta"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"property"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"og:description\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"content"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"Web / mobile app development and consulting across different cycles of your product life.\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"Meta"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"name"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"description\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":":content"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"pageDescriptionRef\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" />"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"Head"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" </"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"div"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":">"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"</"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"template"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":">"}]}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"how-do-i-set-meta-tags-with-nuxt-content-v2"},"children":[{"type":"text","value":"How do I set META tags with Nuxt Content v2?"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Managing Meta tags in Nuxt Content is made very easy."}]},{"type":"element","tag":"h3","props":{"id":"front-matter"},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Front-matter"}]},{"type":"text","value":":"}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"Front-matter"}]},{"type":"text","value":" is a convention of Markdown-based CMS to provide meta-data to pages, like description or title. In Nuxt Content, the front-matter uses the YAML syntax with "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"key: value"}]},{"type":"text","value":" pairs."}]}]},{"type":"element","tag":"code","props":{"code":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\n---\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{}},"children":[{"type":"text","value":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\n---"}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"usecontenthead"},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"useContentHead()"}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is basically the same as "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead()"}]},{"type":"text","value":" that we talked about earlier."}]},{"type":"element","tag":"blockquote","props":{},"children":[{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://content.nuxtjs.org/guide/writing/markdown#front-matter","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"useContentHead()"}]},{"type":"text","value":" is a composable providing a binding between your content data and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useHead()"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"code","props":{"code":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\nimage:\n src: '/assets/image.jpg'\n alt: 'An image showcasing My Page.'\n width: 400\n height: 300\nhead:\n meta:\n - name: 'keywords'\n content: 'nuxt, vue, content'\n - name: 'robots'\n content: 'index, follow'\n - name: 'author'\n content: 'NuxtLabs'\n---\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{}},"children":[{"type":"text","value":"yourArticle.md\n\n---\ntitle: Managing SEO (Meta) tags in Nuxt 3 and Nuxt Content 2\ndescription: Your article description.\nimage:\n src: '/assets/image.jpg'\n alt: 'An image showcasing My Page.'\n width: 400\n height: 300\nhead:\n meta:\n - name: 'keywords'\n content: 'nuxt, vue, content'\n - name: 'robots'\n content: 'index, follow'\n - name: 'author'\n content: 'NuxtLabs'\n---"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Moreover, you can dynamically use "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"Nuxt Meta components"}]},{"type":"text","value":" to set Meta tags on the article page. To see a real-world example of setting Meta tags in the Nuxt 3 project, you can check our "},{"type":"element","tag":"a","props":{"href":"https://github.com/XDEVS-PRO/XDEVS-website","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"repo"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There is definitely more than one way to set Meta tags in the Nuxt 3 framework. Is it bad or good? It's up to you. Having the possibility to make the same thing in multiple ways may be confusing for some people, including myself, but as Nuxt 3 is getting released, I believe we will get more clarification regarding adding Meta tags :)"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"adding-meta-tags-in-nuxt-3-and-nuxt-content-2","depth":2,"text":"Adding Meta tags in Nuxt 3 and Nuxt Content 2","children":[{"id":"nuxtconfigts","depth":3,"text":"Nuxt.config.ts"},{"id":"usehead-composable","depth":3,"text":"useHead composable"},{"id":"usehead-title-templates","depth":3,"text":"useHead Title Templates"},{"id":"definepagemeta","depth":3,"text":"definePageMeta"},{"id":"meta-components","depth":3,"text":"Meta components"}]},{"id":"how-do-i-set-meta-tags-with-nuxt-content-v2","depth":2,"text":"How do I set META tags with Nuxt Content v2?","children":[{"id":"front-matter","depth":3,"text":"Front-matter:"},{"id":"usecontenthead","depth":3,"text":"useContentHead()"},{"id":"conclusion","depth":3,"text":"Conclusion"}]}]}},"_type":"markdown","_id":"content:blog:Nuxt3-NuxtContent2-meta-tags.md","_source":"content","_file":"blog/Nuxt3-NuxtContent2-meta-tags.md","_extension":"md"},{"_path":"/blog/next_js_vs_remix","_draft":false,"_partial":false,"_empty":false,"title":"Next.js vs. Remix.","description":"Nowadays, a new React framework is no news. It seems like they are multiplying each day, so why are we focusing on Remix and Next.js today?","excerpt":{"type":"root","children":[{"type":"element","tag":"h1","props":{"id":"nextjs-vs-remix"},"children":[{"type":"text","value":"Next.js vs. Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nowadays, a new React framework is no news. It seems like they are multiplying each day, so why are we focusing on Remix and Next.js today? Well, Next.js is definitely the most popular choice for building SSR and SSG React applications, and Remix might be the next developer's favorite React framework. They have a lot in common and a lot more differences."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this article we will talk about:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#story-of-the-two"},"children":[{"type":"text","value":"Story of the two frameworks"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#nextjs"},"children":[{"type":"text","value":"Next.js"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#remix"},"children":[{"type":"text","value":"Remix"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#comparison-of-remix-and-nextjs"},"children":[{"type":"text","value":"Comparison of Next.js and Remix"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#routing"},"children":[{"type":"text","value":"Routing"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#nested-routes"},"children":[{"type":"text","value":"Nested Routes"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#dynamic-routes"},"children":[{"type":"text","value":"Dynamic Routes"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#data-loading"},"children":[{"type":"text","value":"Data Loading"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#sessions-and-cookies"},"children":[{"type":"text","value":"Sessions and Cookies"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#working-with-forms"},"children":[{"type":"text","value":"Working with Forms"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#styling"},"children":[{"type":"text","value":"Styling"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#seo"},"children":[{"type":"text","value":"SEO"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#other-comparisons"},"children":[{"type":"text","value":"Other Comparisons"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#conclusion"},"children":[{"type":"text","value":"Conclusion"}]}]}]},{"type":"element","tag":"h2","props":{"id":"story-of-the-two"},"children":[{"type":"text","value":"Story of the two"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To better understand the competition between the two, let's first look into their story."}]},{"type":"element","tag":"h3","props":{"id":"nextjs"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next.js was first released as an open-source project on GitHub on October 25, 2016. It is a project of the Vercel (ex-ZEIT) company. Google has donated to the Next.js project, contributing 43 pull requests in 2019, where they helped in pruning unused JavaScript, reducing the loading time, and adding improved metrics. As of March 2020, the framework is used by many large websites, including Netflix, GitHub, Uber, Ticketmaster, and Starbucks. As of now, 12 major versions of the framework were released. Next.js has 86.5k stars on GitHub and 2,541,419 weekly downloads."}]},{"type":"element","tag":"h3","props":{"id":"remix"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Remix is a framework which was made by the same people, who made React Router. Remix's earliest commits on GitHub are dated to early July of 2020. It wasn't open-source from the start, but the strategy changed in late 2021 when Remix became fully open-source. Even though Remix is a relatively new framework, because of its core principles and ideas, it showed great growth in popularity. Remix has 16.2k likes on GitHub and 20,858 weekly downloads."}]},{"type":"element","tag":"h1","props":{"id":"comparison-of-remix-and-nextjs"},"children":[{"type":"text","value":"Comparison of Remix and Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Remix and Next.js are both React frameworks, that allow you to do server-side rendering, which means that both backend and frontend are implemented in the same application. Render happens on the side of a server and the pages are sent to the client with minimal use of JavaScript. However, by the time of writing, Remix doesn't support static site generation."}]},{"type":"element","tag":"h2","props":{"id":"routing"},"children":[{"type":"text","value":"Routing"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The routing system might seem similar at the first glance, but it isn't. What's similar is the file-based routing, where every file in a specific folder is treated as a new route. This specific folder is routes in Remix and pages in Next.js."}]},{"type":"element","tag":"h4","props":{"id":"nextjs-1"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"code","props":{"code":"- pages\n - index.js\n - new-route.js\n - _app.js\n ...\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"- pages\n - index.js\n - new-route.js\n - _app.js\n ...\n"}]}]}]},{"type":"element","tag":"h4","props":{"id":"remix-1"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"code","props":{"code":"- app\n - routes\n - index.js\n - new-route.js\n ...\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"- app\n - routes\n - index.js\n - new-route.js\n ...\n"}]}]}]},{"type":"element","tag":"h3","props":{"id":"nested-routes"},"children":[{"type":"text","value":"Nested Routes"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Because Remix is built on top of React Router, Remix allows you to do nested routing with ease."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It comes with a very powerful route nesting mechanism that can nest other routes in a currently active route to create what would be considered a nested layout of routes. They act like children components that can be mounted or unmounted depending on the currently active URL path."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This nesting is achievable using an Outlet component. The Outlet component is the key to nested routing in Remix as it is used to tell a parent route where to mount a nested child route. Using the Outlet component, you could easily build a hierarchy of deeply nested routes to create a complex nested layout. Through nested routes, Remix can eliminate nearly every loading state as these nested routes are preloaded on the server, creating almost a hybrid of SPA and SSR."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next.js comes with its own router and has support for nested routes but it’s not as easy to achieve a nested routes layout as in Remix."}]},{"type":"element","tag":"h3","props":{"id":"dynamic-routes"},"children":[{"type":"text","value":"Dynamic Routes"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Both Remix and Next.js have support for dynamic routing but have different naming conventions to create one."}]},{"type":"element","tag":"h4","props":{"id":"nextjs-2"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Next.js it’s created using pair of square brackets with the dynamic param’s name inside."}]},{"type":"element","tag":"code","props":{"code":"pages/post/[postid].js\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"pages/post/[postid].js\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then using the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useRouter"}]},{"type":"text","value":" hook provided by Next.js, the URL query param can be gotten."}]},{"type":"element","tag":"h4","props":{"id":"remix-2"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix, to create a dynamic route you should start the name of the dynamic route with a dollar sign."}]},{"type":"element","tag":"code","props":{"code":"routes/post/$postid.jsx\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"routes/post/$postid.jsx\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And because Remix is based on React Router, the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useParam"}]},{"type":"text","value":" hook can be used to access the URL param."}]},{"type":"element","tag":"h2","props":{"id":"data-loading"},"children":[{"type":"text","value":"Data Loading"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We will only talk about SSR here, because, as said above, Remix doesn't support server-side generation (SSG) option."}]},{"type":"element","tag":"h4","props":{"id":"nextjs-3"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Next.js we have a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getServerSideProps"}]},{"type":"text","value":" function, which does the job of loading data on a server, sending it to a React component and rendering it with the data. This data is sent via props."}]},{"type":"element","tag":"code","props":{"code":"export const getServerSideProps = async ({ params, query }) => { \n // abstract API calls\n const userData = await API.getUser(params.id);\n const { id, name } = userData;\n return {props: { id, name }}\n};\n\nexport default function UserPage(props) { \n return ( \n <> \n <p> User ID: {props.id} </p>\n <p> User Name: {props.name} </p> \n </> \n );\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export const getServerSideProps = async ({ params, query }) => { \n // abstract API calls\n const userData = await API.getUser(params.id);\n const { id, name } = userData;\n return {props: { id, name }}\n};\n\nexport default function UserPage(props) { \n return ( \n <> \n <p> User ID: {props.id} </p>\n <p> User Name: {props.name} </p> \n </> \n );\n}\n"}]}]}]},{"type":"element","tag":"h4","props":{"id":"remix-3"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix, however, we have a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useLoaderData"}]},{"type":"text","value":" hook and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"loader"}]},{"type":"text","value":" function, which do the job for us and don't mix client props with server props. Loader function is an equivalent to Next.js "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getServerSideProps"}]},{"type":"text","value":"."}]},{"type":"element","tag":"code","props":{"code":"import { useLoaderData } from \"remix\"; \n\nexport const loader = async ({ params, request }) => { \n // abstract API calls\n const userData = await API.getUser(params.id);\n const { id, name } = userData;\n return { id, name };\n}; \n\nexport default function FirstPage() { \n const { id, name } = useLoaderData();\n return ( \n <> \n <p> User ID: {id} </p> \n <p> User Name: {name} </p> \n </> \n );\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"import { useLoaderData } from \"remix\"; \n\nexport const loader = async ({ params, request }) => { \n // abstract API calls\n const userData = await API.getUser(params.id);\n const { id, name } = userData;\n return { id, name };\n}; \n\nexport default function FirstPage() { \n const { id, name } = useLoaderData();\n return ( \n <> \n <p> User ID: {id} </p> \n <p> User Name: {name} </p> \n </> \n );\n}\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"sessions-and-cookies"},"children":[{"type":"text","value":"Sessions and Cookies"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are no built-in tools to interact with cookies or sessions in Next.js. You can use a library for that like Cookie.js or NextAuth.js, which would solve your problem."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix, you get full support for cookies and sessions out of the box. You can generate a cookie by calling a function, then serialize or parse data to store or read it."}]},{"type":"element","tag":"code","props":{"code":"import { createCookie } from \"remix\";\n\nconst cookie = createCookie(\"user\", {\n expires: new Date(Date.now() + 60),\n httpOnly: true,\n maxAge: 60,\n path: \"/\",\n sameSite: \"lax\",\n secrets: [\"1s2e3c4r5e6t\"],\n secure: true\n});\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"import { createCookie } from \"remix\";\n\nconst cookie = createCookie(\"user\", {\n expires: new Date(Date.now() + 60),\n httpOnly: true,\n maxAge: 60,\n path: \"/\",\n sameSite: \"lax\",\n secrets: [\"1s2e3c4r5e6t\"],\n secure: true\n});\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"working-with-forms"},"children":[{"type":"text","value":"Working with Forms"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Working with forms is a pain in React. And Next.js is not much different from React when it comes to forms. You would need to implement everything yourself or use a library."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Remix's approach is different and took a lot from the way browsers handle forms natively. All you need to get a form working in Remix is to either use the traditional HTML form tag or import a Form component (both work the same) and set up a form with an HTTP request method set to POST or GET, then enter an action URL to send the data to - which by default will be the same as the route for the form. If the method is set to GET, Remix will execute any export loader function defined in the component, but if the method is POST, Remix will execute any export action function defined in the component."}]},{"type":"element","tag":"code","props":{"code":"export const action = async ({ request }) => {\n const form = await request.formData();\n const content = form.get('description');\n return redirect('/');\n}\n\nexport default function DescriptionForm() {\n return (\n <Form method=\"POST\">\n <label htmlFor=\"description\">\n Description: <textarea name=\"description\" />\n </label>\n <input type=\"submit\" value=\"Add New\" />\n </Form>\n )\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"export const action = async ({ request }) => {\n const form = await request.formData();\n const content = form.get('description');\n return redirect('/');\n}\n\nexport default function DescriptionForm() {\n return (\n <Form method=\"POST\">\n <label htmlFor=\"description\">\n Description: <textarea name=\"description\" />\n </label>\n <input type=\"submit\" value=\"Add New\" />\n </Form>\n )\n}\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"styling"},"children":[{"type":"text","value":"Styling"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next.js supports "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"styled-jsx"}]},{"type":"text","value":" as a CSS-in-JS solution by default. It also has built-in support for CSS modules and Vanilla CSS out of the box. You can also add any other styling library, like "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"styled-components"}]},{"type":"text","value":", with a few lines of configurations."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The primary way to style in Remix is by linking to traditional CSS style sheets placed in the “styles” directory by exporting a Links function in a component. The "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<Links/>"}]},{"type":"text","value":" function is used to inject whatever stylesheet which needs to be loaded for a specific route module and the styles are fetched in parallel when loading the route. This stylesheet is then automatically removed when we leave the route to optimize the amount of CSS you’re sending per page."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As a result, styling in Remix boils down to using CSS files that can be attached to the website via the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"<link rel=\"stylesheet\">"}]},{"type":"text","value":". There’s support for CSS frameworks and libraries right out of the box, but not those that require bundler or compiler integration. Only those that can generate actual CSS files that can be linked to your remix application. Additionally, Remix supports runtime CSS frameworks like styled-components, which are evaluated at runtime but need no bundler integration."}]},{"type":"element","tag":"h2","props":{"id":"seo"},"children":[{"type":"text","value":"SEO"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Next.js, you can achieve a better SEO by importing the built-in "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"next/head"}]},{"type":"text","value":" as a component into your pages or routes and then use it to define all the various meta info needed for that page inside this ‘head’ component as direct children."}]},{"type":"element","tag":"code","props":{"code":"import Head from 'next/head'\n\nexport default function Page() {\n return (\n <div>\n <Head>\n <title>Page Title\n \n \n ...\n \n )\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"import Head from 'next/head'\n\nexport default function Page() {\n return (\n
\n \n Page Title\n \n \n ...\n
\n )\n}\n"}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix you would use a special "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"Meta"}]},{"type":"text","value":" component inside of a page's tag."}]},{"type":"element","tag":"code","props":{"code":"import { Meta } from 'remix'\n\nexport const meta = () => {\n return {\n title: 'Page Title',\n description: 'Page Description'\n }\n}\n\nexport default function Page() {\n return (\n \n \n \n \n \n ...\n \n \n )\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"text","value":"import { Meta } from 'remix'\n\nexport const meta = () => {\n return {\n title: 'Page Title',\n description: 'Page Description'\n }\n}\n\nexport default function Page() {\n return (\n \n \n \n \n \n ...\n \n \n )\n}\n"}]}]}]},{"type":"element","tag":"h2","props":{"id":"other-comparisons"},"children":[{"type":"text","value":"Other Comparisons"}]},{"type":"element","tag":"table","props":{},"children":[{"type":"element","tag":"thead","props":{},"children":[{"type":"element","tag":"tr","props":{},"children":[{"type":"element","tag":"th","props":{"align":null},"children":[]},{"type":"element","tag":"th","props":{"align":null},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"th","props":{"align":null},"children":[{"type":"text","value":"Remix"}]}]}]},{"type":"element","tag":"tbody","props":{},"children":[{"type":"element","tag":"tr","props":{},"children":[{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"Image Optimization"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"✅"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"❌"}]}]},{"type":"element","tag":"tr","props":{},"children":[{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"Google AMP"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"✅"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"❌"}]}]},{"type":"element","tag":"tr","props":{},"children":[{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"TypeScript Support"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"✅"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"✅"}]}]},{"type":"element","tag":"tr","props":{},"children":[{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"Internationalized Routing"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"✅"}]},{"type":"element","tag":"td","props":{"align":null},"children":[{"type":"text","value":"❌"}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Summarizing everything above, I can definitely say that Remix is a great framework, yet, it is a little early to take it to production. Despite that, it is always great to have a competition when it comes to frameworks and Remix is a perfect competitor for Next.js. To understand if Remix is a good option for your project, I would highly recommend you to read "},{"type":"element","tag":"a","props":{"href":"https://remix.run/blog/remix-vs-next","rel":["nofollow","noopener","noreferrer"],"target":"_blank"},"children":[{"type":"text","value":"this article"}]},{"type":"text","value":" by Remix's Co-Founder Ryan Florence, who is talking about performance differences between Next.js and Remix."}]}]},"topic":"Next.js","createdAt":1655420400000,"category":"Web development","image":"/blog/next.js_vs_remix/next.js_vs_remix.png","head":{"image":"/blog/next.js_vs_remix/next.js_vs_remix.png"},"alt":"Next.js vs. Remix.","author":{"name":"Daniil Krutogolov","bio":"Front-end Developer","img":"/blog/authors/daniil.webp"},"tags":["Next.js","Remix"],"body":{"type":"root","children":[{"type":"element","tag":"h1","props":{"id":"nextjs-vs-remix"},"children":[{"type":"text","value":"Next.js vs. Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Nowadays, a new React framework is no news. It seems like they are multiplying each day, so why are we focusing on Remix and Next.js today? Well, Next.js is definitely the most popular choice for building SSR and SSG React applications, and Remix might be the next developer's favorite React framework. They have a lot in common and a lot more differences."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In this article we will talk about:"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#story-of-the-two"},"children":[{"type":"text","value":"Story of the two frameworks"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#nextjs"},"children":[{"type":"text","value":"Next.js"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#remix"},"children":[{"type":"text","value":"Remix"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#comparison-of-remix-and-nextjs"},"children":[{"type":"text","value":"Comparison of Next.js and Remix"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#routing"},"children":[{"type":"text","value":"Routing"}]},{"type":"element","tag":"ul","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#nested-routes"},"children":[{"type":"text","value":"Nested Routes"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#dynamic-routes"},"children":[{"type":"text","value":"Dynamic Routes"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#data-loading"},"children":[{"type":"text","value":"Data Loading"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#sessions-and-cookies"},"children":[{"type":"text","value":"Sessions and Cookies"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#working-with-forms"},"children":[{"type":"text","value":"Working with Forms"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#styling"},"children":[{"type":"text","value":"Styling"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#seo"},"children":[{"type":"text","value":"SEO"}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#other-comparisons"},"children":[{"type":"text","value":"Other Comparisons"}]}]}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#conclusion"},"children":[{"type":"text","value":"Conclusion"}]}]}]},{"type":"element","tag":"h2","props":{"id":"story-of-the-two"},"children":[{"type":"text","value":"Story of the two"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"To better understand the competition between the two, let's first look into their story."}]},{"type":"element","tag":"h3","props":{"id":"nextjs"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next.js was first released as an open-source project on GitHub on October 25, 2016. It is a project of the Vercel (ex-ZEIT) company. Google has donated to the Next.js project, contributing 43 pull requests in 2019, where they helped in pruning unused JavaScript, reducing the loading time, and adding improved metrics. As of March 2020, the framework is used by many large websites, including Netflix, GitHub, Uber, Ticketmaster, and Starbucks. As of now, 12 major versions of the framework were released. Next.js has 86.5k stars on GitHub and 2,541,419 weekly downloads."}]},{"type":"element","tag":"h3","props":{"id":"remix"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Remix is a framework which was made by the same people, who made React Router. Remix's earliest commits on GitHub are dated to early July of 2020. It wasn't open-source from the start, but the strategy changed in late 2021 when Remix became fully open-source. Even though Remix is a relatively new framework, because of its core principles and ideas, it showed great growth in popularity. Remix has 16.2k likes on GitHub and 20,858 weekly downloads."}]},{"type":"element","tag":"h1","props":{"id":"comparison-of-remix-and-nextjs"},"children":[{"type":"text","value":"Comparison of Remix and Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Remix and Next.js are both React frameworks, that allow you to do server-side rendering, which means that both backend and frontend are implemented in the same application. Render happens on the side of a server and the pages are sent to the client with minimal use of JavaScript. However, by the time of writing, Remix doesn't support static site generation."}]},{"type":"element","tag":"h2","props":{"id":"routing"},"children":[{"type":"text","value":"Routing"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The routing system might seem similar at the first glance, but it isn't. What's similar is the file-based routing, where every file in a specific folder is treated as a new route. This specific folder is routes in Remix and pages in Next.js."}]},{"type":"element","tag":"h4","props":{"id":"nextjs-1"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"code","props":{"code":"- pages\n - index.js\n - new-route.js\n - _app.js\n ...\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{}},"children":[{"type":"text","value":"- pages\n - index.js\n - new-route.js\n - _app.js\n ..."}]}]}]}]}]},{"type":"element","tag":"h4","props":{"id":"remix-1"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"code","props":{"code":"- app\n - routes\n - index.js\n - new-route.js\n ...\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{}},"children":[{"type":"text","value":"- app\n - routes\n - index.js\n - new-route.js\n ..."}]}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"nested-routes"},"children":[{"type":"text","value":"Nested Routes"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Because Remix is built on top of React Router, Remix allows you to do nested routing with ease."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It comes with a very powerful route nesting mechanism that can nest other routes in a currently active route to create what would be considered a nested layout of routes. They act like children components that can be mounted or unmounted depending on the currently active URL path."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This nesting is achievable using an Outlet component. The Outlet component is the key to nested routing in Remix as it is used to tell a parent route where to mount a nested child route. Using the Outlet component, you could easily build a hierarchy of deeply nested routes to create a complex nested layout. Through nested routes, Remix can eliminate nearly every loading state as these nested routes are preloaded on the server, creating almost a hybrid of SPA and SSR."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Next.js comes with its own router and has support for nested routes but it’s not as easy to achieve a nested routes layout as in Remix."}]},{"type":"element","tag":"h3","props":{"id":"dynamic-routes"},"children":[{"type":"text","value":"Dynamic Routes"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Both Remix and Next.js have support for dynamic routing but have different naming conventions to create one."}]},{"type":"element","tag":"h4","props":{"id":"nextjs-2"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Next.js it’s created using pair of square brackets with the dynamic param’s name inside."}]},{"type":"element","tag":"code","props":{"code":"pages/post/[postid].js\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{}},"children":[{"type":"text","value":"pages/post/[postid].js"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Then using the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useRouter"}]},{"type":"text","value":" hook provided by Next.js, the URL query param can be gotten."}]},{"type":"element","tag":"h4","props":{"id":"remix-2"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix, to create a dynamic route you should start the name of the dynamic route with a dollar sign."}]},{"type":"element","tag":"code","props":{"code":"routes/post/$postid.jsx\n"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{}},"children":[{"type":"text","value":"routes/post/$postid.jsx"}]}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"And because Remix is based on React Router, the "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useParam"}]},{"type":"text","value":" hook can be used to access the URL param."}]},{"type":"element","tag":"h2","props":{"id":"data-loading"},"children":[{"type":"text","value":"Data Loading"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We will only talk about SSR here, because, as said above, Remix doesn't support server-side generation (SSG) option."}]},{"type":"element","tag":"h4","props":{"id":"nextjs-3"},"children":[{"type":"text","value":"Next.js"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Next.js we have a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getServerSideProps"}]},{"type":"text","value":" function, which does the job of loading data on a server, sending it to a React component and rendering it with the data. This data is sent via props."}]},{"type":"element","tag":"code","props":{"code":"export const getServerSideProps = async ({ params, query }) => { \n // abstract API calls\n const userData = await API.getUser(params.id);\n const { id, name } = userData;\n return {props: { id, name }}\n};\n\nexport default function UserPage(props) { \n return ( \n <> \n

User ID: {props.id}

\n

User Name: {props.name}

\n \n );\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"getServerSideProps"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ({ "}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"params"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"query"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" }) "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// abstract API calls"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"userData"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"await"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"API"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"getUser"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(params.id);"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"id"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"name"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" userData;"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" {props: { id, name }}"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"};"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"default"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"UserPage"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"(props) "}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"{ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ( "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <> "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"> User ID: {props.id} "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"> User Name: {props.name} "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" );"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]}]}]}]},{"type":"element","tag":"h4","props":{"id":"remix-3"},"children":[{"type":"text","value":"Remix"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix, however, we have a "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"useLoaderData"}]},{"type":"text","value":" hook and "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"loader"}]},{"type":"text","value":" function, which do the job for us and don't mix client props with server props. Loader function is an equivalent to Next.js "},{"type":"element","tag":"code-inline","props":{},"children":[{"type":"text","value":"getServerSideProps"}]},{"type":"text","value":"."}]},{"type":"element","tag":"code","props":{"code":"import { useLoaderData } from \"remix\"; \n\nexport const loader = async ({ params, request }) => { \n // abstract API calls\n const userData = await API.getUser(params.id);\n const { id, name } = userData;\n return { id, name };\n}; \n\nexport default function FirstPage() { \n const { id, name } = useLoaderData();\n return ( \n <> \n

User ID: {id}

\n

User Name: {name}

\n \n );\n}\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { useLoaderData } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"remix\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"; "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"loader"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ({ "}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"params"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"request"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" }) "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#6E7781"}},"children":[{"type":"text","value":"// abstract API calls"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"userData"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"await"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"API"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"getUser"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"(params.id);"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"id"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"name"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" userData;"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { id, name };"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}; "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"export"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"default"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"FirstPage"}]},{"type":"element","tag":"span","props":{"style":{"color":"#953800"}},"children":[{"type":"text","value":"() "}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"{ "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"id"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"name"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"useLoaderData"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"();"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" ( "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <> "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"> User ID: {id} "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" <"}]},{"type":"element","tag":"span","props":{"style":{"color":"#116329"}},"children":[{"type":"text","value":"p"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"> User Name: {name} "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" );"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"}"}]}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"sessions-and-cookies"},"children":[{"type":"text","value":"Sessions and Cookies"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"There are no built-in tools to interact with cookies or sessions in Next.js. You can use a library for that like Cookie.js or NextAuth.js, which would solve your problem."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In Remix, you get full support for cookies and sessions out of the box. You can generate a cookie by calling a function, then serialize or parse data to store or read it."}]},{"type":"element","tag":"code","props":{"code":"import { createCookie } from \"remix\";\n\nconst cookie = createCookie(\"user\", {\n expires: new Date(Date.now() + 60),\n httpOnly: true,\n maxAge: 60,\n path: \"/\",\n sameSite: \"lax\",\n secrets: [\"1s2e3c4r5e6t\"],\n secure: true\n});\n","language":"js"},"children":[{"type":"element","tag":"pre","props":{},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"import"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" { createCookie } "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"from"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"remix\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":";"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"const"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"cookie"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"="}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"createCookie"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"user\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":", {"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" expires: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"new"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"Date"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"Date"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":{"color":"#8250DF"}},"children":[{"type":"text","value":"now"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"() "}]},{"type":"element","tag":"span","props":{"style":{"color":"#CF222E"}},"children":[{"type":"text","value":"+"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"60"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"),"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" httpOnly: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"true"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" maxAge: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"60"}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" path: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"/\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" sameSite: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"lax\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":","}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" secrets: ["}]},{"type":"element","tag":"span","props":{"style":{"color":"#0A3069"}},"children":[{"type":"text","value":"\"1s2e3c4r5e6t\""}]},{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"],"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":" secure: "}]},{"type":"element","tag":"span","props":{"style":{"color":"#0550AE"}},"children":[{"type":"text","value":"true"}]}]},{"type":"element","tag":"span","props":{"class":"line"},"children":[{"type":"element","tag":"span","props":{"style":{"color":"#24292F"}},"children":[{"type":"text","value":"});"}]}]}]}]}]},{"type":"element","tag":"h2","props":{"id":"working-with-forms"},"children":[{"type":"text","value":"Working with Forms"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Working with forms is a pain in React. And Next.js is not much different from React when it comes to forms. You would need to implement everything yourself or use a library."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Remix's approach is different and took a lot from the way browsers handle forms natively. All you need to get a form working in Remix is to either use the traditional HTML form tag or import a Form component (both work the same) and set up a form with an HTTP request method set to POST or GET, then enter an action URL to send the data to - which by default will be the same as the route for the form. If the method is set to GET, Remix will execute any export loader function defined in the component, but if the method is POST, Remix will execute any export action function defined in the component."}]},{"type":"element","tag":"code","props":{"code":"export const action = async ({ request }) => {\n const form = await request.formData();\n const content = form.get('description');\n return redirect('/');\n}\n\nexport default function DescriptionForm() {\n return (\n
\n