{"id":93245,"date":"2025-02-17T08:22:46","date_gmt":"2025-02-17T08:22:46","guid":{"rendered":"https:\/\/peraltafinancing.com\/analytics\/calculate-readability-scores-for-content\/"},"modified":"2025-02-17T08:22:46","modified_gmt":"2025-02-17T08:22:46","slug":"calculate-readability-scores-for-content","status":"publish","type":"post","link":"https:\/\/fivemor.com\/?p=93245","title":{"rendered":"Calculate Readability Scores For Content"},"content":{"rendered":"<p> <br \/>\n<\/p>\n<div>\n<p>There are lots of different <a href=\"https:\/\/readable.com\/features\/readability-formulas\/\">readability formulas<\/a> out there, which seek to provide an index on how <em>readable<\/em> any given excerpt of text is. Typically, these formulas output a <strong>grade-level score<\/strong>, which indicates, roughly, the level of education required to read the text excerpt with ease.<\/p>\n<p>Any \u201cquality index\u201d that seeks to reduce the complexity of something as multi-faceted as <em>reading<\/em> should be subject to scrutiny. This is true for Bounce Rate, this is true for Time On Page, and this is true for a <em>readability score<\/em>.<\/p>\n<div style=\"aspect-ratio: 996 \/ 397;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/readability-score-google-analytics.jpg\" title=\"Readability score in Google Analytics\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"397\" width=\"996\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/readability-score-google-analytics.jpg#ZgotmplZ\" alt=\"Readability score in Google Analytics\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p><strong>However<\/strong>, I do think it\u2019s interesting metadata to collect for your content. Who knows, perhaps you\u2019ll find correlations between the difficulty of reading any piece of text and the amount of <a href=\"https:\/\/www.simoahava.com\/analytics\/track-content-engagement-part-2\/\">engagement<\/a> that the content engenders.<\/p>\n<p>In this article, I\u2019ll show you how to create a <strong>Custom JavaScript variable<\/strong> in <a href=\"https:\/\/tagmanager.google.com\/\">Google Tag Manager<\/a> that creates a <a href=\"https:\/\/www.simoahava.com\/analytics\/create-utility-variables-returning-functions\/\">utility function<\/a>. This function can be called with any piece of text (e.g. the text content of your main content DOM element), and it will return an object with a variety of scores based on different readability formulas, as well as a median grade level calculated from these scores.<\/p>\n<p>You can use this information to annotate your Page View hits with Custom Dimensions (with <a href=\"#google-analytics-setup\">a caveat<\/a> regarding its triggers) when sending the data to <a href=\"https:\/\/analytics.google.com\/\">Google Analytics<\/a>.<\/p>\n<p>You can also send the data to a  <a href=\"https:\/\/www.simoahava.com\/analytics\/getting-started-with-google-analytics-app-web\/\">Google Analytics: App + Web<\/a> property ready for that juicy <a href=\"https:\/\/www.simoahava.com\/analytics\/enable-bigquery-export-google-analytics-app-web\/\">BigQuery data export<\/a>.<\/p>\n<p>I\u2019ll show you how to do both in this guide.<\/p>\n<blockquote>\n<p>Thanks to <strong>Munaz Anjum<\/strong> for inspiring me to write this article!<\/p>\n<\/blockquote>\n<p>                <span class=\"simmer\"><br \/>\n  <span class=\"close\">X<\/span><\/p>\n<p>\n    <span class=\"fa fa-md fa-bell\"\/><br \/>\n    <strong>The Simmer Newsletter<\/strong>\n  <\/p>\n<p>\n    Subscribe to the <a href=\"https:\/\/www.simoahava.com\/newsletter\/\">Simmer newsletter<\/a> to get the latest news and content from Simo Ahava into your email inbox!\n  <\/p>\n<p>  <\/span><\/p>\n<h2 id=\"the-custom-javascript-variable\">The Custom JavaScript variable<\/h2>\n<p>In this chapter, we\u2019ll go over the Custom JavaScript variable you\u2019ll need to create to make this work.<\/p>\n<p>\u201cWhy a Custom JavaScript variable? Why not a <a href=\"https:\/\/www.simoahava.com\/analytics\/custom-templates-guide-for-google-tag-manager\/\">custom template<\/a>?\u201d I hear you ask. <em>I know!<\/em> This would be <em>perfect<\/em> for a custom template. Alas, templates do not support the full extent of regular expressions yet, and they are absolutely vital for the algorithms required by the formulae in the variable.<\/p>\n<h3 id=\"what-youll-get\">What you\u2019ll get<\/h3>\n<p>The Custom JavaScript variable returns a <strong>function<\/strong>, which you can then invoke with a string in another Custom JavaScript variable or a Custom HTML tag.<\/p>\n<p>When you call the function with a string, e.g.:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> readabilityFunction = {{readabilityFunction}};\n\n<span style=\"color:#00a\">var<\/span> text = <span style=\"color:#a50\">'At the heart of this paper lies the elusive concept of \\\n<\/span><span style=\"color:#a50\">variation: how speakers can simultaneously share a common knowledge \\\n<\/span><span style=\"color:#a50\">of a unified language system and develop it in idiosyncratic and unique \\\n<\/span><span style=\"color:#a50\">ways. Studies of variation do not come without their fair share of \\\n<\/span><span style=\"color:#a50\">controversy. Since they necessarily incorporate the attention to detail \\\n<\/span><span style=\"color:#a50\">that a descriptivist approach demands together with a level of abstraction \\\n<\/span><span style=\"color:#a50\">that is likewise required by all studies of linguistic phenomena, the \\\n<\/span><span style=\"color:#a50\">results are often as debatable as they are revelatory. It is thus the \\\n<\/span><span style=\"color:#a50\">researcher\u2019s job to describe the phenomenon as lucidly as possible, \\\n<\/span><span style=\"color:#a50\">without drawing conclusions that extend beyond the scope of the data at hand.'<\/span>\n\nconsole.log(readabilityFunction(text));\n\n<span style=\"color:#aaa;font-style:italic\">\/\/ Outputs\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/ {\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   automatedReadabilityIndex: 15.48,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   colemanLiauIndex: 13.12,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   fleschKincaidGrade: 16.41,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   fleschReadingEase: 28.17,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   linsearWriteFormula: 18.25,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   medianGrade: 17,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   readingTime: 27.34,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   rix: 9.5,\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/   smogIndex: 17.41\n<\/span><span style=\"color:#aaa;font-style:italic\">\/\/ }\n<\/span><\/code><\/pre>\n<\/div>\n<p>This particular excerpt (from my <a href=\"https:\/\/helda.helsinki.fi\/bitstream\/handle\/10138\/19347\/intermed.pdf\">master\u2019s thesis<\/a>) has a median readability grade of <strong>17<\/strong> which means, loosely translated, that it takes around 17 years of <em>education<\/em> to read text like this with ease. The <strong>reading time<\/strong> is around 27 seconds.<\/p>\n<p>The object for <strong>the article you are reading<\/strong> looks like this (ouch!):<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\">{\n  automatedReadabilityIndex: <span style=\"color:#099\">15.48<\/span>,\n  colemanLiauIndex: <span style=\"color:#099\">3.77<\/span>,\n  fleschKincaidGrade: <span style=\"color:#099\">16.96<\/span>,\n  fleschReadingEase: <span style=\"color:#099\">39.67<\/span>,\n  linsearWriteFormula: <span style=\"color:#099\">13.2<\/span>,\n  medianGrade: <span style=\"color:#099\">15<\/span>,\n  readingTime: <span style=\"color:#099\">1524.22<\/span>,\n  rix: <span style=\"color:#099\">7.11<\/span>,\n  smogIndex: <span style=\"color:#099\">15.85<\/span>\n}\n<\/code><\/pre>\n<\/div>\n<p>I\u2019ll share what these different numbers and names mean in a bit.<\/p>\n<h3 id=\"variable-contents\">Variable contents<\/h3>\n<p>The code is a JavaScript rewrite of the <a href=\"https:\/\/github.com\/shivam5992\/textstat\/\">textstat.py<\/a> Python library. I did not include any readability grades that rely on an English wordlist (so any formulae that require a definition of what is a \u201ccommon\u201d or \u201ceasy\u201d word in English is ignored).<\/p>\n<p><strong>Create a new Custom JavaScript variable<\/strong>, give it a name (e.g. <code>readabilityFunction<\/code>), and copy-paste the following JavaScript in the body.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#00a\">function<\/span>(text) {\n\n    <span style=\"color:#aaa;font-style:italic\">\/* To speed the script up, you can set a sampling rate in words. For example, if you set\n<\/span><span style=\"color:#aaa;font-style:italic\">     * sampleLimit to 1000, only the first 1000 words will be parsed from the input text.\n<\/span><span style=\"color:#aaa;font-style:italic\">     * Set to 0 to never sample.\n<\/span><span style=\"color:#aaa;font-style:italic\">     *\/<\/span>     \n    <span style=\"color:#00a\">var<\/span> sampleLimit = <span style=\"color:#099\">1000<\/span>;\n    \n    <span style=\"color:#aaa;font-style:italic\">\/\/ Manual rewrite of the textstat Python library (https:\/\/github.com\/shivam5992\/textstat\/)\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    \n    <span style=\"color:#aaa;font-style:italic\">\/* \n<\/span><span style=\"color:#aaa;font-style:italic\">     * Regular expression to identify a sentence. No, it's not perfect. \n<\/span><span style=\"color:#aaa;font-style:italic\">     * Fails e.g. with abbreviations and similar constructs mid-sentence.\n<\/span><span style=\"color:#aaa;font-style:italic\">     *\/<\/span>\n    <span style=\"color:#00a\">var<\/span> sentenceRegex = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">RegExp<\/span>(<span style=\"color:#a50\">'[.?!]\\\\s[^a-z]'<\/span>, <span style=\"color:#a50\">'g'<\/span>);\n    \n    <span style=\"color:#aaa;font-style:italic\">\/*\n<\/span><span style=\"color:#aaa;font-style:italic\">     * Regular expression to identify a syllable. No, it's not perfect either.\n<\/span><span style=\"color:#aaa;font-style:italic\">     * It's based on English, so other languages with different vowel \/ consonant distributions\n<\/span><span style=\"color:#aaa;font-style:italic\">     * and syllable definitions need a rewrite.\n<\/span><span style=\"color:#aaa;font-style:italic\">     * Inspired by https:\/\/bit.ly\/2VK9dz1\n<\/span><span style=\"color:#aaa;font-style:italic\">     *\/<\/span>\n    <span style=\"color:#00a\">var<\/span> syllableRegex = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">RegExp<\/span>(<span style=\"color:#a50\">'[aiouy]+e*|e(?!d$|ly).|[td]ed|le$'<\/span>, <span style=\"color:#a50\">'g'<\/span>);\n    \n    <span style=\"color:#aaa;font-style:italic\">\/\/ Baseline for FRE - English only\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">var<\/span> freBase = {\n      base: <span style=\"color:#099\">206.835<\/span>,\n      sentenceLength: <span style=\"color:#099\">1.015<\/span>,\n      syllablesPerWord: <span style=\"color:#099\">84.6<\/span>,\n      syllableThreshold: <span style=\"color:#099\">3<\/span>\n    };\n    \n    <span style=\"color:#00a\">var<\/span> cache = {};\n    \n    <span style=\"color:#00a\">var<\/span> punctuation = [<span style=\"color:#a50\">'!'<\/span>,<span style=\"color:#a50\">'\"'<\/span>,<span style=\"color:#a50\">'#'<\/span>,<span style=\"color:#a50\">'$'<\/span>,<span style=\"color:#a50\">'%'<\/span>,<span style=\"color:#a50\">'&amp;'<\/span>,<span style=\"color:#a50\">'\\''<\/span>,<span style=\"color:#a50\">'('<\/span>,<span style=\"color:#a50\">')'<\/span>,<span style=\"color:#a50\">'*'<\/span>,<span style=\"color:#a50\">'+'<\/span>,<span style=\"color:#a50\">','<\/span>,<span style=\"color:#a50\">'-'<\/span>,<span style=\"color:#a50\">'.'<\/span>,<span style=\"color:#a50\">'\/'<\/span>,<span style=\"color:#a50\">':'<\/span>,<span style=\"color:#a50\">';'<\/span>,<span style=\"color:#a50\">',<span style=\"color:#a50\">'='<\/span>,<span style=\"color:#a50\">'&gt;'<\/span>,<span style=\"color:#a50\">'?'<\/span>,<span style=\"color:#a50\">'@'<\/span>,<span style=\"color:#a50\">'['<\/span>,<span style=\"color:#a50\">']'<\/span>,<span style=\"color:#a50\">'^'<\/span>,<span style=\"color:#a50\">'_'<\/span>,<span style=\"color:#a50\">'`'<\/span>,<span style=\"color:#a50\">'{'<\/span>,<span style=\"color:#a50\">'|'<\/span>,<span style=\"color:#a50\">'}'<\/span>,<span style=\"color:#a50\">'~'<\/span>];\n    \n    <span style=\"color:#00a\">var<\/span> legacyRound = <span style=\"color:#00a\">function<\/span>(number, precision) {\n      <span style=\"color:#00a\">var<\/span> k = <span style=\"color:#0aa\">Math<\/span>.pow(<span style=\"color:#099\">10<\/span>, (precision || <span style=\"color:#099\">0<\/span>));\n      <span style=\"color:#00a\">return<\/span> <span style=\"color:#0aa\">Math<\/span>.floor((number * k) + <span style=\"color:#099\">0.5<\/span> * <span style=\"color:#0aa\">Math<\/span>.sign(number)) \/ k;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> charCount = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">if<\/span> (cache.charCount) <span style=\"color:#00a\">return<\/span> cache.charCount;\n      <span style=\"color:#00a\">if<\/span> (sampleLimit &gt; <span style=\"color:#099\">0<\/span>) text = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>, sampleLimit).join(<span style=\"color:#a50\">' '<\/span>);\n      text = text.replace(<span style=\"color:#099\">\/\\s\/g<\/span>, <span style=\"color:#a50\">''<\/span>);\n      <span style=\"color:#00a\">return<\/span> cache.charCount = text.length;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> removePunctuation = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">return<\/span> text.split(<span style=\"color:#a50\">''<\/span>).filter(<span style=\"color:#00a\">function<\/span>(c) {\n        <span style=\"color:#00a\">return<\/span> punctuation.indexOf(c) === -<span style=\"color:#099\">1<\/span>;\n      }).join(<span style=\"color:#a50\">''<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> letterCount = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">if<\/span> (sampleLimit &gt; <span style=\"color:#099\">0<\/span>) text = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>, sampleLimit).join(<span style=\"color:#a50\">' '<\/span>);\n      text = text.replace(<span style=\"color:#099\">\/\\s\/g<\/span>, <span style=\"color:#a50\">''<\/span>);\n      <span style=\"color:#00a\">return<\/span> removePunctuation(text).length;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> lexiconCount = <span style=\"color:#00a\">function<\/span>(text, useCache, ignoreSample) {\n      <span style=\"color:#00a\">if<\/span> (useCache &amp;&amp; cache.lexiconCount) <span style=\"color:#00a\">return<\/span> cache.lexiconCount;\n      <span style=\"color:#00a\">if<\/span> (ignoreSample !== <span style=\"color:#00a\">true<\/span> &amp;&amp; sampleLimit &gt; <span style=\"color:#099\">0<\/span>) text = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>, sampleLimit).join(<span style=\"color:#a50\">' '<\/span>);\n      text = removePunctuation(text);\n      <span style=\"color:#00a\">var<\/span> lexicon = text.split(<span style=\"color:#a50\">' '<\/span>).length;\n      <span style=\"color:#00a\">return<\/span> useCache ? cache.lexiconCount = lexicon : lexicon;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> getWords = <span style=\"color:#00a\">function<\/span>(text, useCache) {\n      <span style=\"color:#00a\">if<\/span> (useCache &amp;&amp; cache.getWords) <span style=\"color:#00a\">return<\/span> cache.getWords;\n      <span style=\"color:#00a\">if<\/span> (sampleLimit &gt; <span style=\"color:#099\">0<\/span>) text = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>, sampleLimit).join(<span style=\"color:#a50\">' '<\/span>);\n      text = text.toLowerCase();\n      text = removePunctuation(text);\n      <span style=\"color:#00a\">var<\/span> words = text.split(<span style=\"color:#a50\">' '<\/span>);\n      <span style=\"color:#00a\">return<\/span> useCache ? cache.getWords = words : words;\n    }\n    \n    <span style=\"color:#00a\">var<\/span> syllableCount = <span style=\"color:#00a\">function<\/span>(text, useCache) {\n      <span style=\"color:#00a\">if<\/span> (useCache &amp;&amp; cache.syllableCount) <span style=\"color:#00a\">return<\/span> cache.syllableCount;\n      <span style=\"color:#00a\">var<\/span> count = <span style=\"color:#099\">0<\/span>;\n      <span style=\"color:#00a\">var<\/span> syllables = getWords(text, useCache).reduce(<span style=\"color:#00a\">function<\/span>(a, c) {  \n        <span style=\"color:#00a\">return<\/span> a + (c.match(syllableRegex) || [<span style=\"color:#099\">1<\/span>]).length;\n      }, <span style=\"color:#099\">0<\/span>);\n      <span style=\"color:#00a\">return<\/span> useCache ? cache.syllableCount = syllables : syllables;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> polySyllableCount = <span style=\"color:#00a\">function<\/span>(text, useCache) {\n      <span style=\"color:#00a\">var<\/span> count = <span style=\"color:#099\">0<\/span>;\n      getWords(text, useCache).forEach(<span style=\"color:#00a\">function<\/span>(word) {\n        <span style=\"color:#00a\">var<\/span> syllables = syllableCount(word);\n        <span style=\"color:#00a\">if<\/span> (syllables &gt;= <span style=\"color:#099\">3<\/span>) {\n          count += <span style=\"color:#099\">1<\/span>;\n        }\n      });\n      <span style=\"color:#00a\">return<\/span> count;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> sentenceCount = <span style=\"color:#00a\">function<\/span>(text, useCache) {\n      <span style=\"color:#00a\">if<\/span> (useCache &amp;&amp; cache.sentenceCount) <span style=\"color:#00a\">return<\/span> cache.sentenceCount;\n      <span style=\"color:#00a\">if<\/span> (sampleLimit &gt; <span style=\"color:#099\">0<\/span>) text = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>, sampleLimit).join(<span style=\"color:#a50\">' '<\/span>);\n      <span style=\"color:#00a\">var<\/span> ignoreCount = <span style=\"color:#099\">0<\/span>;\n      <span style=\"color:#00a\">var<\/span> sentences = text.split(sentenceRegex);\n      sentences.forEach(<span style=\"color:#00a\">function<\/span>(s) {\n        <span style=\"color:#00a\">if<\/span> (lexiconCount(s, <span style=\"color:#00a\">true<\/span>, <span style=\"color:#00a\">false<\/span>) 2<\/span>) { ignoreCount += <span style=\"color:#099\">1<\/span>; }\n      });\n      <span style=\"color:#00a\">var<\/span> count = <span style=\"color:#0aa\">Math<\/span>.max(<span style=\"color:#099\">1<\/span>, sentences.length - ignoreCount);\n      <span style=\"color:#00a\">return<\/span> useCache ? cache.sentenceCount = count : count;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> avgSentenceLength = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> avg = lexiconCount(text, <span style=\"color:#00a\">true<\/span>) \/ sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">return<\/span> legacyRound(avg, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> avgSyllablesPerWord = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> avg = syllableCount(text, <span style=\"color:#00a\">true<\/span>) \/ lexiconCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">return<\/span> legacyRound(avg, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> avgCharactersPerWord = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> avg = charCount(text) \/ lexiconCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">return<\/span> legacyRound(avg, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> avgLettersPerWord = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> avg = letterCount(text, <span style=\"color:#00a\">true<\/span>) \/ lexiconCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">return<\/span> legacyRound(avg, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> avgSentencesPerWord = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> avg = sentenceCount(text, <span style=\"color:#00a\">true<\/span>) \/ lexiconCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">return<\/span> legacyRound(avg, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> fleschReadingEase = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> sentenceLength = avgSentenceLength(text);\n      <span style=\"color:#00a\">var<\/span> syllablesPerWord = avgSyllablesPerWord(text);\n      <span style=\"color:#00a\">return<\/span> legacyRound(\n        freBase.base - \n        freBase.sentenceLength * sentenceLength - \n        freBase.syllablesPerWord * syllablesPerWord,\n        <span style=\"color:#099\">2<\/span>\n      );\n    };\n    \n    <span style=\"color:#00a\">var<\/span> fleschKincaidGrade = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> sentenceLength = avgSentenceLength(text);\n      <span style=\"color:#00a\">var<\/span> syllablesPerWord = avgSyllablesPerWord(text);\n      <span style=\"color:#00a\">return<\/span> legacyRound(\n        <span style=\"color:#099\">0.39<\/span> * sentenceLength +\n        <span style=\"color:#099\">11.8<\/span> * syllablesPerWord -\n        <span style=\"color:#099\">15.59<\/span>,\n        <span style=\"color:#099\">2<\/span>\n      );\n    };\n    \n    <span style=\"color:#00a\">var<\/span> smogIndex = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> sentences = sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">if<\/span> (sentences &gt;= <span style=\"color:#099\">3<\/span>) {\n        <span style=\"color:#00a\">var<\/span> polySyllables = polySyllableCount(text, <span style=\"color:#00a\">true<\/span>);\n        <span style=\"color:#00a\">var<\/span> smog = <span style=\"color:#099\">1.043<\/span> * (<span style=\"color:#0aa\">Math<\/span>.pow(polySyllables * (<span style=\"color:#099\">30<\/span> \/ sentences), <span style=\"color:#099\">0.5<\/span>)) + <span style=\"color:#099\">3.1291<\/span>;\n        <span style=\"color:#00a\">return<\/span> legacyRound(smog, <span style=\"color:#099\">2<\/span>);\n      }\n      <span style=\"color:#00a\">return<\/span> <span style=\"color:#099\">0.0<\/span>;\n    };\n    \n    <span style=\"color:#00a\">var<\/span> colemanLiauIndex = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> letters = legacyRound(avgLettersPerWord(text) * <span style=\"color:#099\">100<\/span>, <span style=\"color:#099\">2<\/span>);\n      <span style=\"color:#00a\">var<\/span> sentences = legacyRound(avgSentencesPerWord(text) * <span style=\"color:#099\">100<\/span>, <span style=\"color:#099\">2<\/span>);\n      <span style=\"color:#00a\">var<\/span> coleman = <span style=\"color:#099\">0.0588<\/span> * letters - <span style=\"color:#099\">0.296<\/span> * sentences - <span style=\"color:#099\">15.8<\/span>;\n      <span style=\"color:#00a\">return<\/span> legacyRound(coleman, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> automatedReadabilityIndex = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> chars = charCount(text);\n      <span style=\"color:#00a\">var<\/span> words = lexiconCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">var<\/span> sentences = sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">var<\/span> a = chars \/ words;\n      <span style=\"color:#00a\">var<\/span> b = words \/ sentences;\n      <span style=\"color:#00a\">var<\/span> readability = (\n        <span style=\"color:#099\">4.71<\/span> * legacyRound(a, <span style=\"color:#099\">2<\/span>) +\n        <span style=\"color:#099\">0.5<\/span> * legacyRound(b, <span style=\"color:#099\">2<\/span>) -\n        <span style=\"color:#099\">21.43<\/span>\n      );\n      <span style=\"color:#00a\">return<\/span> legacyRound(readability, <span style=\"color:#099\">2<\/span>); \n    };\n    \n    <span style=\"color:#00a\">var<\/span> linsearWriteFormula = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> easyWord = <span style=\"color:#099\">0<\/span>;\n      <span style=\"color:#00a\">var<\/span> difficultWord = <span style=\"color:#099\">0<\/span>;\n      <span style=\"color:#00a\">var<\/span> roughTextFirst100 = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>,<span style=\"color:#099\">100<\/span>).join(<span style=\"color:#a50\">' '<\/span>);\n      <span style=\"color:#00a\">var<\/span> plainTextListFirst100 = getWords(text, <span style=\"color:#00a\">true<\/span>).slice(<span style=\"color:#099\">0<\/span>,<span style=\"color:#099\">100<\/span>);\n      plainTextListFirst100.forEach(<span style=\"color:#00a\">function<\/span>(word) {\n        <span style=\"color:#00a\">if<\/span> (syllableCount(word) 3) {\n          easyWord += <span style=\"color:#099\">1<\/span>;\n        } <span style=\"color:#00a\">else<\/span> {\n          difficultWord += <span style=\"color:#099\">1<\/span>;\n        }\n      });\n      <span style=\"color:#00a\">var<\/span> number = (easyWord + difficultWord * <span style=\"color:#099\">3<\/span>) \/ sentenceCount(roughTextFirst100);\n      <span style=\"color:#00a\">if<\/span> (number 20) {\n        number -= <span style=\"color:#099\">2<\/span>;\n      }\n      <span style=\"color:#00a\">return<\/span> legacyRound(number \/ <span style=\"color:#099\">2<\/span>, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> rix = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> words = getWords(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">var<\/span> longCount = words.filter(<span style=\"color:#00a\">function<\/span>(word) {\n        <span style=\"color:#00a\">return<\/span> word.length &gt; <span style=\"color:#099\">6<\/span>;\n      }).length;\n      <span style=\"color:#00a\">var<\/span> sentencesCount = sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n      <span style=\"color:#00a\">return<\/span> legacyRound(longCount \/ sentencesCount, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#00a\">var<\/span> readingTime = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> wordsPerSecond = <span style=\"color:#099\">4.17<\/span>;\n      <span style=\"color:#aaa;font-style:italic\">\/\/ To get full reading time, ignore cache and sample\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">return<\/span> legacyRound(lexiconCount(text, <span style=\"color:#00a\">false<\/span>, <span style=\"color:#00a\">true<\/span>) \/ wordsPerSecond, <span style=\"color:#099\">2<\/span>);\n    };\n    \n    <span style=\"color:#aaa;font-style:italic\">\/\/ Build textStandard\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>    <span style=\"color:#00a\">var<\/span> grade = [];\n    <span style=\"color:#00a\">var<\/span> obj = {};\n    (<span style=\"color:#00a\">function<\/span>() {\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ FRE\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> fre = obj.fleschReadingEase = fleschReadingEase(text);\n      <span style=\"color:#00a\">if<\/span> (fre 100 &amp;&amp; fre &gt;= <span style=\"color:#099\">90<\/span>) {\n        grade.push(<span style=\"color:#099\">5<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (fre 90 &amp;&amp; fre &gt;= <span style=\"color:#099\">80<\/span>) {\n        grade.push(<span style=\"color:#099\">6<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (fre 80 &amp;&amp; fre &gt;= <span style=\"color:#099\">70<\/span>) {\n        grade.push(<span style=\"color:#099\">7<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (fre 70 &amp;&amp; fre &gt;= <span style=\"color:#099\">60<\/span>) {\n        grade.push(<span style=\"color:#099\">8<\/span>);\n        grade.push(<span style=\"color:#099\">9<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (fre 60 &amp;&amp; fre &gt;= <span style=\"color:#099\">50<\/span>) {\n        grade.push(<span style=\"color:#099\">10<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (fre 50 &amp;&amp; fre &gt;= <span style=\"color:#099\">40<\/span>) {\n        grade.push(<span style=\"color:#099\">11<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (fre 40 &amp;&amp; fre &gt;= <span style=\"color:#099\">30<\/span>) {\n        grade.push(<span style=\"color:#099\">12<\/span>);\n      } <span style=\"color:#00a\">else<\/span> {\n        grade.push(<span style=\"color:#099\">13<\/span>);\n      }\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ FK\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> fk = obj.fleschKincaidGrade = fleschKincaidGrade(text);\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.floor(fk));\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.ceil(fk));\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ SMOG\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> smog = obj.smogIndex = smogIndex(text);\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.floor(smog));\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.ceil(smog));\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ CL\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> cl = obj.colemanLiauIndex = colemanLiauIndex(text);\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.floor(cl));\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.ceil(cl));\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ ARI\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> ari = obj.automatedReadabilityIndex = automatedReadabilityIndex(text);\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.floor(ari));\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.ceil(ari));\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ LWF\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> lwf = obj.linsearWriteFormula = linsearWriteFormula(text);\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.floor(lwf));\n      grade.push(<span style=\"color:#0aa\">Math<\/span>.ceil(lwf));\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ RIX\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">var<\/span> rixScore = obj.rix = rix(text);\n      <span style=\"color:#00a\">if<\/span> (rixScore &gt;= <span style=\"color:#099\">7.2<\/span>) {\n        grade.push(<span style=\"color:#099\">13<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 7.2 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">6.2<\/span>) {\n        grade.push(<span style=\"color:#099\">12<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 6.2 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">5.3<\/span>) {\n        grade.push(<span style=\"color:#099\">11<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 5.3 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">4.5<\/span>) {\n        grade.push(<span style=\"color:#099\">10<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 4.5 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">3.7<\/span>) {\n        grade.push(<span style=\"color:#099\">9<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 3.7 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">3.0<\/span>) {\n        grade.push(<span style=\"color:#099\">8<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 3.0 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">2.4<\/span>) {\n        grade.push(<span style=\"color:#099\">7<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 2.4 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">1.8<\/span>) {\n        grade.push(<span style=\"color:#099\">6<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 1.8 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">1.3<\/span>) {\n        grade.push(<span style=\"color:#099\">5<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 1.3 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">0.8<\/span>) {\n        grade.push(<span style=\"color:#099\">4<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 0.8 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">0.5<\/span>) {\n        grade.push(<span style=\"color:#099\">3<\/span>);\n      } <span style=\"color:#00a\">else<\/span> <span style=\"color:#00a\">if<\/span> (rixScore 0.5 &amp;&amp; rixScore &gt;= <span style=\"color:#099\">0.2<\/span>) {\n        grade.push(<span style=\"color:#099\">2<\/span>);\n      } <span style=\"color:#00a\">else<\/span> {\n        grade.push(<span style=\"color:#099\">1<\/span>);\n      }\n      \n      <span style=\"color:#aaa;font-style:italic\">\/\/ Find median grade\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      grade = grade.sort(<span style=\"color:#00a\">function<\/span>(a, b) { <span style=\"color:#00a\">return<\/span> a - b; });\n      <span style=\"color:#00a\">var<\/span> midPoint = <span style=\"color:#0aa\">Math<\/span>.floor(grade.length \/ <span style=\"color:#099\">2<\/span>);\n      <span style=\"color:#00a\">var<\/span> medianGrade = legacyRound(\n        grade.length % <span style=\"color:#099\">2<\/span> ? \n        grade[midPoint] : \n        (grade[midPoint-<span style=\"color:#099\">1<\/span>] + grade[midPoint]) \/ <span style=\"color:#099\">2.0<\/span>\n      );\n      obj.medianGrade = medianGrade;\n      \n    })();\n    \n    obj.readingTime = readingTime(text);\n      \n    <span style=\"color:#00a\">return<\/span> obj;\n  };\n}\n<\/code><\/pre>\n<\/div>\n<p>It\u2019s a mouthful, so let\u2019s go over each formula together with the code that relates to it.<\/p>\n<h4 id=\"setup\">Setup<\/h4>\n<p>The first couple of steps in the variable establish much of what follows.<\/p>\n<p>Running regular expressions can be <strong>slow<\/strong>. If you have an article of 5000 words, for example, counting the syllables of every single word can take a looooooong time, and can be hazardous if executed at page load.<\/p>\n<p>I\u2019ve introduced the <code>sampleLimit<\/code> variable, which basically establishes a maximum sample size to run the readability calculations against. If <code>sampleLimit<\/code> is set to the default of <code>1000<\/code>, the script will sample the first 1000 words of the input. The end result should be in the <em>ball park<\/em> of a score calculated against the full text, but this of course depends on what type of text is in question.<\/p>\n<p>If you want to avoid sampling, set <code>sampleLimit<\/code> to <code>0<\/code>.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> sentenceRegex = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">RegExp<\/span>(<span style=\"color:#a50\">'[.?!]\\\\s[^a-z]'<\/span>, <span style=\"color:#a50\">'g'<\/span>);\n<span style=\"color:#00a\">var<\/span> syllableRegex = <span style=\"color:#00a\">new<\/span> <span style=\"color:#0aa\">RegExp<\/span>(<span style=\"color:#a50\">'[aiouy]+e*|e(?!d$|ly).|[td]ed|le$'<\/span>, <span style=\"color:#a50\">'g'<\/span>);\n<\/code><\/pre>\n<\/div>\n<p>The first regular expression is used to split a chunk of text in <em>sentences<\/em>. <strong>No, it\u2019s not perfect<\/strong>.<\/p>\n<p>But that\u2019s OK &#8211; we\u2019re looking for abstractions and the more text you have the more the score will converge towards a norm.<\/p>\n<p>The second regular expression counts the number of <em>syllables<\/em> in a text. <strong>No, it\u2019s not perfect either<\/strong>. It\u2019s based on English, and perhaps other Germanic languages, but syllabification can change from language to language so if you want to analyze content in other languages, you need to modify the regex.<\/p>\n<p>The rest of the setup steps are listed here.<\/p>\n<table>\n<thead>\n<tr>\n<th>Function \/ variable signature<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>freBase<\/code><\/td>\n<td>The baseline numbers for calculating the Flesch Reading-Ease score in the English language.<\/td>\n<\/tr>\n<tr>\n<td><code>cache<\/code><\/td>\n<td>Utility that caches most of the calculations, so that the regexes are run just once for the cached items.<\/td>\n<\/tr>\n<tr>\n<td><code>punctuation<\/code><\/td>\n<td>List of punctuation symbols.<\/td>\n<\/tr>\n<tr>\n<td><code>legacyRound()<\/code><\/td>\n<td>Function to round the input number to the given precision.<\/td>\n<\/tr>\n<tr>\n<td><code>charCount()<\/code><\/td>\n<td>Count the characters in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>removePunctuation()<\/code><\/td>\n<td>Remove all punctuation from the input.<\/td>\n<\/tr>\n<tr>\n<td><code>letterCount()<\/code><\/td>\n<td>Count the letters in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>lexiconCount()<\/code><\/td>\n<td>Count the words in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>getWords()<\/code><\/td>\n<td>Returns the words in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>syllableCount()<\/code><\/td>\n<td>Count the syllables in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>polySyllableCount()<\/code><\/td>\n<td>Count the number of words with three or more syllables in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>sentenceCount()<\/code><\/td>\n<td>Count the number of sentences in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>avgSentenceLength()<\/code><\/td>\n<td>Count the average length of sentences (number of words) in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>avgSyllablesPerWord()<\/code><\/td>\n<td>Count the average number of syllables per word in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>avgCharactersPerWord()<\/code><\/td>\n<td>Count the average number of characters per word in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>avgLettersPerWord()<\/code><\/td>\n<td>Count the average number of letters per word in the input.<\/td>\n<\/tr>\n<tr>\n<td><code>avgSentencesPerWord()<\/code><\/td>\n<td>Count the average number of sentences per word in the input.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>These utilities are used to calculate the readability formulae.<\/p>\n<h4 id=\"1-flesch-reading-ease\">1. Flesch Reading-Ease<\/h4>\n<p>The <a href=\"%5Bhttps:\/\/en.wikipedia.org\/wiki\/Flesch%E2%80%93Kincaid_readability_tests#Flesch_reading_ease%5D(https:\/\/en.wikipedia.org\/wiki\/Flesch%E2%80%93Kincaid_readability_tests#Flesch_reading_ease)\">Flesch Reading-Ease<\/a> test is probably one of the better known readability tests. It\u2019s used by e.g. <a href=\"https:\/\/yoast.com\/flesch-reading-ease-score\/\">Yoast<\/a> and <a href=\"https:\/\/www.grammarly.com\/blog\/readability-scores\/\">Grammarly<\/a> to calculate their readability scores.<\/p>\n<p>For the English language, the algorithm is:<\/p>\n<p><code>206.835 - 1.015 x (words \/ sentences) - 84.6 x (syllables \/ words)<\/code><\/p>\n<p>This outputs a score between 1 and 100, where the higher the score, the easier to read the text is.<\/p>\n<p>A score between <strong>70 and 80<\/strong> would be considered easy to read for a 7th grader in the US.<\/p>\n<p>In the Custom JavaScript variable, Flesch Reading-Ease is generated like this:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> fleschReadingEase = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> sentenceLength = avgSentenceLength(text);\n  <span style=\"color:#00a\">var<\/span> syllablesPerWord = avgSyllablesPerWord(text);\n  <span style=\"color:#00a\">return<\/span> legacyRound(\n    freBase.base - \n    freBase.sentenceLength * sentenceLength - \n    freBase.syllablesPerWord * syllablesPerWord,\n    <span style=\"color:#099\">2<\/span>\n  );\n};\n<\/code><\/pre>\n<\/div>\n<h4 id=\"2-flesch-kincaid-grade\">2. Flesch-Kincaid Grade<\/h4>\n<p>The <a href=\"%5Bhttps:\/\/en.wikipedia.org\/wiki\/Flesch%E2%80%93Kincaid_readability_tests#Flesch%E2%80%93Kincaid_grade_level%5D(https:\/\/en.wikipedia.org\/wiki\/Flesch%E2%80%93Kincaid_readability_tests#Flesch%E2%80%93Kincaid_grade_level)\">Flesch-Kincaid Grade Level<\/a> score outputs a number that corresponds to the U.S. grade level generally required to understand the text. If the score returns a number higher than 10, it can also be used to calculate the <strong>years of education<\/strong> required to understand the text.<\/p>\n<p>The algorithm is:<\/p>\n<p><code>0.39 x (words \/ sentences) + 11.8 x (syllables \/ words) - 15.59<\/code><\/p>\n<p>In the Custom JavaScript variable, this translates to:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-JavaScript\" data-lang=\"JavaScript\"><span style=\"color:#00a\">var<\/span> fleschKincaidGrade = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> sentenceLength = avgSentenceLength(text);\n  <span style=\"color:#00a\">var<\/span> syllablesPerWord = avgSyllablesPerWord(text);\n  <span style=\"color:#00a\">return<\/span> legacyRound(\n    <span style=\"color:#099\">0.39<\/span> * sentenceLength +\n    <span style=\"color:#099\">11.8<\/span> * syllablesPerWord -\n    <span style=\"color:#099\">15.59<\/span>,\n    <span style=\"color:#099\">2<\/span>\n  );\n};\n<\/code><\/pre>\n<\/div>\n<h4 id=\"3-smog-grade\">3. SMOG grade<\/h4>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/SMOG\">SMOG grade<\/a>, short for <strong>S<\/strong>imple <strong>M<\/strong>easure <strong>o<\/strong>f <strong>G<\/strong>obbledygook, estimates the years of education required to understand any given text. It is particularly preferred (over Flesch-Kincaid) in the healthcare industry for content design.<\/p>\n<p>The algorithm is:<\/p>\n<p><code>1.0430 x squareroot(polysyllables x (30 \/ sentences)) + 3.1291<\/code><\/p>\n<p>In the variable, this would be:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> smogIndex = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> sentences = sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n  <span style=\"color:#00a\">if<\/span> (sentences &gt;= <span style=\"color:#099\">3<\/span>) {\n    <span style=\"color:#00a\">var<\/span> polySyllables = polySyllableCount(text, <span style=\"color:#00a\">true<\/span>);\n    <span style=\"color:#00a\">var<\/span> smog = <span style=\"color:#099\">1.043<\/span> * <span style=\"color:#0aa\">Math<\/span>.pow(polySyllables * (<span style=\"color:#099\">30<\/span> \/ sentences), <span style=\"color:#099\">0.5<\/span>) + <span style=\"color:#099\">3.1291<\/span>;\n    <span style=\"color:#00a\">return<\/span> legacyRound(smog, <span style=\"color:#099\">2<\/span>);\n  }\n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#099\">0.0<\/span>;\n};\n<\/code><\/pre>\n<\/div>\n<p>Note that the formula ignores content that has three or fewer sentences, as the grade would lose any semblance of accuracy in those cases.<\/p>\n<p>Just a note on the JavaScript, using <code>Math.pow(x, y)<\/code> calculates <code>x<\/code> to the power of <code>y<\/code>. When you set <code>y<\/code> to <code>0.5<\/code>, you get the square root of <code>x<\/code>.<\/p>\n<h4 id=\"4-coleman-liau-index\">4. Coleman-Liau index<\/h4>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Coleman%E2%80%93Liau_index\">Coleman-Liau index<\/a> again outputs an approximation of the U.S. grade level required to understand the text. It\u2019s better suited for computer programs as it doesn\u2019t care about the complexity of <strong>syllables<\/strong> but rather relies on <strong>character counts<\/strong>.<\/p>\n<p>The algorithm is:<\/p>\n<p><code>0.0588 x average_letters_per_100_words - 0.296 x average_sentences_per_100_words - 15.8<\/code><\/p>\n<p>In JavaScript, this would be:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> colemanLiauIndex = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> letters = legacyRound(avgLettersPerWord(text) * <span style=\"color:#099\">100<\/span>, <span style=\"color:#099\">2<\/span>);\n  <span style=\"color:#00a\">var<\/span> sentences = legacyRound(avgSentencesPerWord(text) * <span style=\"color:#099\">100<\/span>, <span style=\"color:#099\">2<\/span>);\n  <span style=\"color:#00a\">var<\/span> coleman = <span style=\"color:#099\">0.0588<\/span> * letters - <span style=\"color:#099\">0.296<\/span> * sentences - <span style=\"color:#099\">15.8<\/span>;\n  <span style=\"color:#00a\">return<\/span> legacyRound(coleman, <span style=\"color:#099\">2<\/span>);\n};\n<\/code><\/pre>\n<\/div>\n<p>Now, you can see how abstract this is, again. It calculates the average number of letters in a word <em>from the entire text<\/em>, and multiplies this by 100 to get the average letters in a 100 word sample. Same thing for sentences. Thus, the number gets more accurate the larger the data sample.<\/p>\n<h4 id=\"5-automated-readability-index\">5. Automated Readability Index<\/h4>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Automated_readability_index\">Automated Readability Index<\/a> returns yet again a U.S. grade level score thought to correspond with how readable the text is.<\/p>\n<p>The formula for ARI is:<\/p>\n<p><code>4.71 x (characters \/ words) + 0.5 x (words \/ sentences) - 21.43<\/code><\/p>\n<p>Similar to the Coleman-Liau index, ARI relies on characters rather than syllables, so is thus friendlier to machine calculation but can lead to a more diverse spread of scores compared to syllable-based systems.<\/p>\n<p>In JavaScript, ARI is calculated like this:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> automatedReadabilityIndex = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> chars = charCount(text);\n  <span style=\"color:#00a\">var<\/span> words = lexiconCount(text, <span style=\"color:#00a\">true<\/span>);\n  <span style=\"color:#00a\">var<\/span> sentences = sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n  <span style=\"color:#00a\">var<\/span> a = chars \/ words;\n  <span style=\"color:#00a\">var<\/span> b = words \/ sentences;\n  <span style=\"color:#00a\">var<\/span> readability = (\n    <span style=\"color:#099\">4.71<\/span> * legacyRound(a, <span style=\"color:#099\">2<\/span>) +\n    <span style=\"color:#099\">0.5<\/span> * legacyRound(b, <span style=\"color:#099\">2<\/span>) -\n    <span style=\"color:#099\">21.43<\/span>\n  );\n  <span style=\"color:#00a\">return<\/span> legacyRound(readability, <span style=\"color:#099\">2<\/span>);\n};\n<\/code><\/pre>\n<\/div>\n<h4 id=\"6-linsear-write\">6. Linsear Write<\/h4>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Linsear_Write\">Linsear Write<\/a> metric uses a sample of 100 words to calculate the U.S. grade level required to understand the text. It also divides the text into \u201ceasy words\u201d (two syllables or less) and \u201cdifficult words\u201d (three syllables or more).<\/p>\n<p>The algorithm is:<\/p>\n<p><code>r = (count_of_easy_words + 3 x count_of_difficult_words) \/ sentences<\/code><\/p>\n<p><code>if r &gt; 20, result = r \/ 2<\/code><\/p>\n<p><code>if r <\/code><\/p>\n<p>In JavaScript, this would be:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> linsearWriteFormula = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> easyWord = <span style=\"color:#099\">0<\/span>;\n  <span style=\"color:#00a\">var<\/span> difficultWord = <span style=\"color:#099\">0<\/span>;\n  <span style=\"color:#00a\">var<\/span> roughTextFirst100 = text.split(<span style=\"color:#a50\">' '<\/span>).slice(<span style=\"color:#099\">0<\/span>,<span style=\"color:#099\">100<\/span>).join(<span style=\"color:#a50\">' '<\/span>);\n  <span style=\"color:#00a\">var<\/span> plainTextListFirst100 = getWords(text, <span style=\"color:#00a\">true<\/span>).slice(<span style=\"color:#099\">0<\/span>,<span style=\"color:#099\">100<\/span>);\n  plainTextListFirst100.forEach(<span style=\"color:#00a\">function<\/span>(word) {\n    <span style=\"color:#00a\">if<\/span> (syllableCount(word) 3) {\n      easyWord += <span style=\"color:#099\">1<\/span>;\n    } <span style=\"color:#00a\">else<\/span> {\n      difficultWord += <span style=\"color:#099\">1<\/span>;\n    }\n  });\n  <span style=\"color:#00a\">var<\/span> number = (easyWord + difficultWord * <span style=\"color:#099\">3<\/span>) \/ sentenceCount(roughTextFirst100);\n  <span style=\"color:#00a\">if<\/span> (number 20) {\n    number -= <span style=\"color:#099\">2<\/span>;\n  }\n  <span style=\"color:#00a\">return<\/span> legacyRound(number \/ <span style=\"color:#099\">2<\/span>, <span style=\"color:#099\">2<\/span>);\n};\n<\/code><\/pre>\n<\/div>\n<p>Yeah, it\u2019s a bit messy. The problem is that the \u201ceasy words\u201d and \u201cdifficult words\u201d need to be calculated from the lexicon without any punctuation, and the sentence count needs to be calculated from a sample with punctuation intact.<\/p>\n<p>In any case, the end result is the Linsear Write score for the text input with decent accuracy.<\/p>\n<h4 id=\"7-rix\">7. Rix<\/h4>\n<p><a href=\"https:\/\/readable.com\/features\/readability-formulas\/#rix\">Rix<\/a> is quite plainly the number of long words divided by the number of sentences in the text. A long word is a word with more than six characters.<\/p>\n<p>The resulting score can be <a href=\"https:\/\/readable.com\/features\/readability-formulas\/#rix\">converted to U.S. grade-level<\/a>.<\/p>\n<p>In JavaScript, you can calculate Rix like this:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">var<\/span> rix = <span style=\"color:#00a\">function<\/span>(text) {\n  <span style=\"color:#00a\">var<\/span> words = getWords(text, <span style=\"color:#00a\">true<\/span>);\n  <span style=\"color:#00a\">var<\/span> longCount = words.filter(<span style=\"color:#00a\">function<\/span>(word) {\n    <span style=\"color:#00a\">return<\/span> word.length &gt; <span style=\"color:#099\">6<\/span>;\n  }).length;\n  <span style=\"color:#00a\">var<\/span> sentencesCount = sentenceCount(text, <span style=\"color:#00a\">true<\/span>);\n  <span style=\"color:#00a\">return<\/span> legacyRound(longCount \/ sentencesCount, <span style=\"color:#099\">2<\/span>);\n};\n<\/code><\/pre>\n<\/div>\n<h4 id=\"8-reading-time\">8. Reading time<\/h4>\n<p>To calculate reading time of the text, we use <a href=\"https:\/\/www.healthguidance.org\/entry\/13263\/1\/What-Is-the-Average-Reading-Speed-and-the-Best-Rate-of-Reading.html\">the benchmark<\/a> of <strong>250 words per minute<\/strong> read by the average adult. This translates to <strong>4.17<\/strong> words per second.<\/p>\n<p>The algorithm is simple:<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\">    <span style=\"color:#00a\">var<\/span> readingTime = <span style=\"color:#00a\">function<\/span>(text) {\n      <span style=\"color:#00a\">var<\/span> wordsPerSecond = <span style=\"color:#099\">4.17<\/span>;\n      <span style=\"color:#aaa;font-style:italic\">\/\/ To get full reading time, ignore cache and sample\n<\/span><span style=\"color:#aaa;font-style:italic\"\/>      <span style=\"color:#00a\">return<\/span> legacyRound(lexiconCount(text, <span style=\"color:#00a\">false<\/span>, <span style=\"color:#00a\">true<\/span>) \/ wordsPerSecond, <span style=\"color:#099\">2<\/span>);\n    };\n<\/code><\/pre>\n<\/div>\n<p>This outputs a value in <strong>seconds<\/strong> corresponding to the time it would take for the average adult to read the text.<\/p>\n<h4 id=\"median-grade\">Median grade<\/h4>\n<p>The median grade is calculated by pushing all the <strong>grades<\/strong> (both lower and upper bound integers for floating point values), and then taking the <strong>median<\/strong> grade.<\/p>\n<p>This is not a scientific result in any way. Heck, the whole concept of <strong>readability<\/strong> escapes scientific scrutiny (just look at the number of different tests with different values!). If you want to modify it, you could use the <strong>average<\/strong> grade as well (take both rounded down and rounded up to get the grade spread). Or you could find what grade is the <strong>most common<\/strong> in the whole spread and use that instead.<\/p>\n<p>Regardless, I\u2019ve chosen <strong>median<\/strong> as it excludes the outliers nicely and typically the grades would converge enough to have the median reflect the average anyway.<\/p>\n<h3 id=\"how-to-use-the-utility-variable\">How to use the utility variable<\/h3>\n<p>Once you create and save the Custom JavaScript variable, you can invoke it from other Custom JavaScript variables or Custom HTML tags.<\/p>\n<p>For example, let\u2019s say you have all the main content of any given page stored in an HTML element that can be accessed with the <a href=\"https:\/\/www.simoahava.com\/analytics\/css-selector-guide-google-tag-manager\/\">CSS selector<\/a> <code>.post-content .main-content-wrap<\/code>.<\/p>\n<p>Here\u2019s what a handful of different Custom JavaScript variables would look like, each returning a different value from the <code>readabilityFunction<\/code> output.<\/p>\n<p>There are many ways to skin this cat, so feel free to get creative.<\/p>\n<h4 id=\"get-the-flesch-kincaid-score\">Get the Flesch-Kincaid Score<\/h4>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">var<\/span> el = <span style=\"color:#0aa\">document<\/span>.querySelector(<span style=\"color:#a50\">'.post-content .main-content-wrap'<\/span>).textContent;\n  <span style=\"color:#00a\">return<\/span> {{readabilityFunction}}(el).fleschKincaidGrade;\n}\n<\/code><\/pre>\n<\/div>\n<h4 id=\"get-the-median-grade\">Get the median grade<\/h4>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">var<\/span> el = <span style=\"color:#0aa\">document<\/span>.querySelector(<span style=\"color:#a50\">'.post-content .main-content-wrap'<\/span>).textContent;\n  <span style=\"color:#00a\">return<\/span> {{readabilityFunction}}(el).medianGrade;\n}\n<\/code><\/pre>\n<\/div>\n<h4 id=\"get-the-reading-time-in-minutes-and-seconds\">Get the reading time in minutes and seconds<\/h4>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">var<\/span> el = <span style=\"color:#0aa\">document<\/span>.querySelector(<span style=\"color:#a50\">'.post-content .main-content-wrap'<\/span>).textContent;\n  <span style=\"color:#00a\">var<\/span> readingTime = {{readabilityFunction}}(el).readingTime;\n  <span style=\"color:#00a\">return<\/span> <span style=\"color:#0aa\">Math<\/span>.floor(readingTime \/ <span style=\"color:#099\">60<\/span>) + <span style=\"color:#a50\">\"m\"<\/span> + <span style=\"color:#0aa\">Math<\/span>.round(readingTime % <span style=\"color:#099\">60<\/span>) + <span style=\"color:#a50\">\"s\"<\/span>;\n}\n<\/code><\/pre>\n<\/div>\n<p>This would convert a reading time (in seconds) of <code>129.67<\/code> to <code>\"2m10s\"<\/code>.<\/p>\n<h3 id=\"google-analytics-setup\">Google Analytics setup<\/h3>\n<p>Once you have the values you want to access, all you need to do is send them to Google Analytics.<\/p>\n<p>Here\u2019s a sample setup. It sends the <a href=\"#get-the-median-grade\"><strong>median grade<\/strong><\/a> to Google Analytics as a Custom Metric, and it collects the <a href=\"#8-reading-time\"><strong>reading time<\/strong><\/a> as another Custom Metric. To make results easier to scan at a glance, we\u2019ll also send the median grade as a Custom Dimension.<\/p>\n<p>But before we start, here\u2019s a caveat you need to be aware of.<\/p>\n<h4 id=\"dom-ready\">DOM Ready<\/h4>\n<p>If you use <strong>DOM methods<\/strong> to check the readability of content from the web page, you might not be able to use a Google Analytics tag that fires on the <strong>All Pages<\/strong> trigger.<\/p>\n<p>This is because a potential <em>race condition<\/em> can emerge where the <strong>All Pages<\/strong> trigger can fire before your DOM content is available for Google Tag Manager.<\/p>\n<p>In this case, you are left with two options:<\/p>\n<ol>\n<li>Send the readability data with an event (or another pageview) where you set the <code>nonInteraction<\/code> field to <code>true<\/code>.<\/li>\n<li>Delay the Page View hit a bit to fire on a <strong>DOM Ready<\/strong> trigger instead.<\/li>\n<\/ol>\n<p>The main problem with (1) is that you won\u2019t be able to parse the data in your main Page View report (which is the logical place for it), and would need to join the data outside Google Analytics instead (or perhaps use a <strong>custom report<\/strong> creatively).<\/p>\n<p>The main problem with (2) is that you risk missing a fraction of your pageviews because the hit is delayed a bit.<\/p>\n<p>If it\u2019s a <strong>single-page app<\/strong>, you are in luck as you can instruct the developers not to fire <a href=\"https:\/\/www.bounteous.com\/insights\/2018\/03\/30\/single-page-applications-google-analytics\/#page-paths-or-page-titles-are-incongruent-with-application-state\">the virtual pageview event<\/a> until the content has been fully rendered on the page.<\/p>\n<h4 id=\"1-custom-javascript-variable-for-median-grade\">1. Custom JavaScript variable for median grade<\/h4>\n<p>Remember to change the <code>el<\/code> variable assignment to match whatever content you want to evaluate. In this example, it\u2019s an HTML element accessible with the <a href=\"https:\/\/www.simoahava.com\/analytics\/css-selector-guide-google-tag-manager\/\">CSS selector<\/a> <code>.post-content .main-content-wrap<\/code>.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">var<\/span> el = <span style=\"color:#0aa\">document<\/span>.querySelector(<span style=\"color:#a50\">'.post-content .main-content-wrap'<\/span>).textContent;\n  <span style=\"color:#00a\">return<\/span> {{readabilityFunction}}(el).medianGrade;\n}\n<\/code><\/pre>\n<\/div>\n<h4 id=\"2-custom-javascript-variable-for-reading-time\">2. Custom JavaScript variable for reading time<\/h4>\n<p>Remember to change the <code>el<\/code> variable assignment to match whatever content you want to evaluate. In this example, it\u2019s an HTML element accessible with the <a href=\"https:\/\/www.simoahava.com\/analytics\/css-selector-guide-google-tag-manager\/\">CSS selector<\/a> <code>.post-content .main-content-wrap<\/code>.<\/p>\n<div class=\"highlight\">\n<pre style=\"background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4\"><code class=\"language-javascript\" data-lang=\"javascript\"><span style=\"color:#00a\">function<\/span>() {\n  <span style=\"color:#00a\">var<\/span> el = <span style=\"color:#0aa\">document<\/span>.querySelector(<span style=\"color:#a50\">'.post-content .main-content-wrap'<\/span>).textContent;\n  <span style=\"color:#00a\">return<\/span> {{readabilityFunction}}(el).readingTime;\n}\n<\/code><\/pre>\n<\/div>\n<h4 id=\"3-google-analytics---admin---custom-definitions\">3. Google Analytics &#8211; Admin &#8211; Custom Definitions<\/h4>\n<p>Here\u2019s what the <strong>Custom Metric<\/strong> for Reading Time looks like in Google Analytics admin:<\/p>\n<div style=\"aspect-ratio: 796 \/ 477;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/10\/custom-met-in-ga.jpg\" title=\"Custom metric in GA\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"477\" width=\"796\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/10\/custom-met-in-ga.jpg#ZgotmplZ\" alt=\"Custom metric in GA\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>If you want, you can build a <strong>Calculated Metric<\/strong> to get the <em>average<\/em> reading time across pageviews.<\/p>\n<div style=\"aspect-ratio: 645 \/ 409;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/10\/calculated-metric-in-ga.jpg\" title=\"Calculated metric in GA\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"409\" width=\"645\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/10\/calculated-metric-in-ga.jpg#ZgotmplZ\" alt=\"Calculated metric in GA\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here\u2019s what the <strong>Custom Metric<\/strong> for Median Grade looks like:<\/p>\n<div style=\"aspect-ratio: 490 \/ 411;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/custom-metric-median.jpg\" title=\"Custom Metric Median Grade\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"411\" width=\"490\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/custom-metric-median.jpg#ZgotmplZ\" alt=\"Custom Metric Median Grade\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Here\u2019s what the <strong>Custom Dimension<\/strong> for Median Grade looks like in Google Analytics admin:<\/p>\n<div style=\"aspect-ratio: 781 \/ 432;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/10\/custom-dim-in-ga.jpg\" title=\"Custom dimension in GA\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"432\" width=\"781\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/10\/custom-dim-in-ga.jpg#ZgotmplZ\" alt=\"Custom dimension in GA\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h4 id=\"4-google-analytics-tag\">4. Google Analytics tag<\/h4>\n<p>Finally, here\u2019s what a sample Page View tag would look like, modified.<\/p>\n<div style=\"aspect-ratio: 889 \/ 638;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/sample-ga-tag.jpg\" title=\"Sample GA Tag\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"638\" width=\"889\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/sample-ga-tag.jpg#ZgotmplZ\" alt=\"Sample GA Tag\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Just remember the <a href=\"#dom-ready\">caveat<\/a> about <em>DOM ready triggering<\/em> I mentioned above.<\/p>\n<h4 id=\"5-how-to-access-the-results\">5. How to access the results<\/h4>\n<p>The <strong>Custom Dimension<\/strong> will be available as a secondary dimension or in a custom report.<\/p>\n<div style=\"aspect-ratio: 949 \/ 370;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/custom-report.jpg\" title=\"Custom report\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"370\" width=\"949\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/custom-report.jpg#ZgotmplZ\" alt=\"Custom report\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>The <strong>Custom Metrics<\/strong> (and the Calculated Metric if you opted to create one) will be available in custom reports as well.<\/p>\n<p>Note that instead of messing around with awkward custom reports, you might want to extract the data out of Google Analytics using e.g. the <a href=\"https:\/\/developers.google.com\/analytics\/solutions\/google-analytics-spreadsheet-add-on\">Google Sheets add-on<\/a> as this gives you far more flexibility in building your own reports.<\/p>\n<h3 id=\"google-analytics-app--web-setup\">Google Analytics: App + Web setup<\/h3>\n<p>If you want to send the data to the new <a href=\"https:\/\/www.simoahava.com\/analytics\/getting-started-with-google-analytics-app-web\/\">App + Web<\/a> then all the power to you! Setting it up is easy &#8211; just create a new <strong>App + Web event tag<\/strong> for your Page View (you might want to disable the default Page View from the <em>config<\/em> tag), and add the variables as new event parameters.<\/p>\n<p>Make sure this tag, too, triggers on DOM Ready.<\/p>\n<div style=\"aspect-ratio: 898 \/ 613;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/10\/app-web-pageview.jpg\" title=\"App+Web Pageview\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"613\" width=\"898\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/10\/app-web-pageview.jpg#ZgotmplZ\" alt=\"App+Web Pageview\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Once you do this, the events should start showing up in the App + Web streams:<\/p>\n<div style=\"aspect-ratio: 520 \/ 418;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/parameter-in-real-time.jpg\" title=\"App+web real time\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"418\" width=\"520\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/parameter-in-real-time.jpg#ZgotmplZ\" alt=\"App+web real time\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In order to build reports for these parameters, you need to <strong>include them in parameter reporting<\/strong>.<\/p>\n<p>Once you\u2019ve collected some data, head over to <strong>Events<\/strong> -&gt; <strong>All Events<\/strong>, and click the little action menu at the end of the row with the <code>page_view<\/code> event. Select <strong>Edit parameter reporting<\/strong> from this menu.<\/p>\n<div style=\"aspect-ratio: 1408 \/ 192;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/10\/parameter-menu.jpg\" title=\"Parameter menu\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"192\" width=\"1408\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/10\/parameter-menu.jpg#ZgotmplZ\" alt=\"Parameter menu\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>In the overlay that appears, find the two <code>readability_*<\/code> parameters to add them to the list of parameters included in reporting. Set the type of the <em>median grade<\/em> parameter to <strong>Text<\/strong>, and the type of the <em>reading time<\/em> parameter to <strong>Number \/ Seconds<\/strong>.<\/p>\n<div style=\"aspect-ratio: 1152 \/ 405;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/parameter-reporting-setup.jpg\" title=\"Parameter reporting setup\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"405\" width=\"1152\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/parameter-reporting-setup.jpg#ZgotmplZ\" alt=\"Parameter reporting setup\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<p>Once you\u2019ve done these, and once you\u2019ve accumulated some new data, you\u2019ll be able to find the two parameters as their own widgets when you select the <strong>page_view<\/strong> event in the event list, and when moving through the <strong>Analysis<\/strong> reports.<\/p>\n<p>Note that if you\u2019ve configured a <a href=\"https:\/\/www.simoahava.com\/analytics\/enable-bigquery-export-google-analytics-app-web\/\">BigQuery export<\/a>, the parameters will be included whether or not you add them via the event parameter reporting user interface!<\/p>\n<div style=\"aspect-ratio: 803 \/ 658;\" class=\"figure nocaption\">\n<p>    <a href=\"https:\/\/www.simoahava.com\/images\/2019\/11\/bigquery-result.jpg\" title=\"BigQuery result\"><\/p>\n<p>    <img decoding=\"async\" class=\"fig-img\" height=\"658\" width=\"803\" loading=\"lazy\" src=\"https:\/\/www.simoahava.com\/images\/2019\/11\/bigquery-result.jpg#ZgotmplZ\" alt=\"BigQuery result\"\/><\/p>\n<p>    <\/a><\/p>\n<\/div>\n<h2 id=\"summary\">Summary<\/h2>\n<p>Let\u2019s discuss the caveats first.<\/p>\n<p>The script itself is fairly simple, basically chopping down the text into constituent parts and then performing calculations with those parts. However, it can <strong>perform poorly<\/strong> if its fed a lot of content to process. Performance of regular expressions degrade in correlation with the amount of content, and with a large body of text the parsing can disrupt your page load. This is mitigated with the use of a <strong>cache<\/strong> and a <strong>sampling threshold<\/strong>, but you\u2019ll need to tinker with these to get the best accuracy and the best performance.<\/p>\n<p>The <strong>regular expressions are not perfect<\/strong>. Particularly parsing sentences turns out to be quite difficult to manage with clarity, and I have opted for a fairly simple algorithm in the script.<\/p>\n<p>All in all, <strong>readability scores<\/strong> need to be taken with a grain of salt. They abstract away much of what is gained with context, and they know nothing about the background of the reader. They count things like syllables, long words, and short words, and try to assign labels like \u201ceasy\u201d and \u201cdifficult\u201d based on these calculations.<\/p>\n<p>The grade-level abstractions are also calculated based on U.S. averages. Whether you want to draw any conclusions is totally up to you, but I do think how much different the levels would be in a country like Finland, where the education system is somewhat different.<\/p>\n<p>Having said all that, it\u2019s still a fun idea to play around with especially if you\u2019re in the business of creating content. <strong>Readability<\/strong> is a great concept to work towards, and the grades for my own content (almost categorically past college-level) have given me some pause. I think it\u2019s a great way to design content to be as readable as possible, and tools like this should give you some insight.<\/p>\n<p>Whether or not Google Analytics is the right place to measure this remains to be seen. But I would imagine there to be benefits to correlating readability and reading time with overall engagement metrics. Something to optimize against, I think!<\/p>\n<p>Let me know in the comments what you think about this approach!<\/p>\n<\/p><\/div>\n\n","protected":false},"excerpt":{"rendered":"<p>There are lots of different readability formulas out there, which seek to provide an index on how readable any given excerpt of text is. Typically, these formulas output a grade-level score, which indicates, roughly, the level of education required to read the text excerpt with ease. Any \u201cquality index\u201d that seeks to reduce the complexity [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":93246,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12033],"tags":[27865,7222,44591,21885],"dealstore":[],"offerexpiration":[],"class_list":["post-93245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-analytics","tag-calculate","tag-content","tag-readability","tag-scores"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Calculate Readability Scores For Content - Som2ny Network<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fivemor.com\/?p=93245\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Calculate Readability Scores For Content - Som2ny Network\" \/>\n<meta property=\"og:description\" content=\"There are lots of different readability formulas out there, which seek to provide an index on how readable any given excerpt of text is. Typically, these formulas output a grade-level score, which indicates, roughly, the level of education required to read the text excerpt with ease. Any \u201cquality index\u201d that seeks to reduce the complexity [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fivemor.com\/?p=93245\" \/>\n<meta property=\"og:site_name\" content=\"Som2ny Network\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-17T08:22:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"996\" \/>\n\t<meta property=\"og:image:height\" content=\"397\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fivemor.com\/?p=93245#article\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/?p=93245\"},\"author\":{\"name\":\"admin\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\"},\"headline\":\"Calculate Readability Scores For Content\",\"datePublished\":\"2025-02-17T08:22:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=93245\"},\"wordCount\":2944,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=93245#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg\",\"keywords\":[\"Calculate\",\"Content\",\"Readability\",\"Scores\"],\"articleSection\":[\"Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fivemor.com\/?p=93245#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fivemor.com\/?p=93245\",\"url\":\"https:\/\/fivemor.com\/?p=93245\",\"name\":\"Calculate Readability Scores For Content - Som2ny Network\",\"isPartOf\":{\"@id\":\"https:\/\/fivemor.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/fivemor.com\/?p=93245#primaryimage\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/?p=93245#primaryimage\"},\"thumbnailUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg\",\"datePublished\":\"2025-02-17T08:22:46+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fivemor.com\/?p=93245#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fivemor.com\/?p=93245\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/?p=93245#primaryimage\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg\",\"width\":996,\"height\":397},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fivemor.com\/?p=93245#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/fivemor.com\/?bp_activities=1\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Calculate Readability Scores For Content\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fivemor.com\/#website\",\"url\":\"https:\/\/fivemor.com\/\",\"name\":\"Som2ny Network\",\"description\":\"Daily Deals\",\"publisher\":{\"@id\":\"https:\/\/fivemor.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fivemor.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/fivemor.com\/#organization\",\"name\":\"Som2ny Network\",\"url\":\"https:\/\/fivemor.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"contentUrl\":\"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png\",\"width\":300,\"height\":86,\"caption\":\"Som2ny Network\"},\"image\":{\"@id\":\"https:\/\/fivemor.com\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/fivemor.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png\",\"caption\":\"admin\"},\"sameAs\":[\"https:\/\/fivemor.com\"],\"url\":\"https:\/\/fivemor.com\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Calculate Readability Scores For Content - Som2ny Network","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fivemor.com\/?p=93245","og_locale":"en_US","og_type":"article","og_title":"Calculate Readability Scores For Content - Som2ny Network","og_description":"There are lots of different readability formulas out there, which seek to provide an index on how readable any given excerpt of text is. Typically, these formulas output a grade-level score, which indicates, roughly, the level of education required to read the text excerpt with ease. Any \u201cquality index\u201d that seeks to reduce the complexity [&hellip;]","og_url":"https:\/\/fivemor.com\/?p=93245","og_site_name":"Som2ny Network","article_published_time":"2025-02-17T08:22:46+00:00","og_image":[{"width":996,"height":397,"url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg","type":"image\/jpeg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin","Est. reading time":"23 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fivemor.com\/?p=93245#article","isPartOf":{"@id":"https:\/\/fivemor.com\/?p=93245"},"author":{"name":"admin","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371"},"headline":"Calculate Readability Scores For Content","datePublished":"2025-02-17T08:22:46+00:00","mainEntityOfPage":{"@id":"https:\/\/fivemor.com\/?p=93245"},"wordCount":2944,"commentCount":0,"publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"image":{"@id":"https:\/\/fivemor.com\/?p=93245#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg","keywords":["Calculate","Content","Readability","Scores"],"articleSection":["Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fivemor.com\/?p=93245#respond"]}]},{"@type":"WebPage","@id":"https:\/\/fivemor.com\/?p=93245","url":"https:\/\/fivemor.com\/?p=93245","name":"Calculate Readability Scores For Content - Som2ny Network","isPartOf":{"@id":"https:\/\/fivemor.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/fivemor.com\/?p=93245#primaryimage"},"image":{"@id":"https:\/\/fivemor.com\/?p=93245#primaryimage"},"thumbnailUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg","datePublished":"2025-02-17T08:22:46+00:00","breadcrumb":{"@id":"https:\/\/fivemor.com\/?p=93245#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fivemor.com\/?p=93245"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/?p=93245#primaryimage","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2025\/02\/readability-score-google-analytics.jpg","width":996,"height":397},{"@type":"BreadcrumbList","@id":"https:\/\/fivemor.com\/?p=93245#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/fivemor.com\/?bp_activities=1"},{"@type":"ListItem","position":2,"name":"Calculate Readability Scores For Content"}]},{"@type":"WebSite","@id":"https:\/\/fivemor.com\/#website","url":"https:\/\/fivemor.com\/","name":"Som2ny Network","description":"Daily Deals","publisher":{"@id":"https:\/\/fivemor.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fivemor.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/fivemor.com\/#organization","name":"Som2ny Network","url":"https:\/\/fivemor.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/","url":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","contentUrl":"https:\/\/fivemor.com\/wp-content\/uploads\/2026\/07\/4a0953c4-logo-300x86-1.png","width":300,"height":86,"caption":"Som2ny Network"},"image":{"@id":"https:\/\/fivemor.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/fivemor.com\/#\/schema\/person\/b85e3c3dc0e1daea076524dc8810c371","name":"admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/fivemor.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/729ae85bf62b9917e93538db2f2688ca?s=96&r=g&default=https%3A%2F%2Ffivemor.com%2Fwp-content%2Fplugins%2Fbuddypress-first-letter-avatar%2Fimages%2Fdefault%2F96%2Flatin_a.png","caption":"admin"},"sameAs":["https:\/\/fivemor.com"],"url":"https:\/\/fivemor.com\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/93245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=93245"}],"version-history":[{"count":0,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/posts\/93245\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=\/wp\/v2\/media\/93246"}],"wp:attachment":[{"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=93245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=93245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=93245"},{"taxonomy":"dealstore","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fdealstore&post=93245"},{"taxonomy":"offerexpiration","embeddable":true,"href":"https:\/\/fivemor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fofferexpiration&post=93245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}