<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>create react app Archives - Alexiev Arts</title>
	<atom:link href="https://alexievarts.com/tag/create-react-app/feed/" rel="self" type="application/rss+xml" />
	<link>https://alexievarts.com/tag/create-react-app/</link>
	<description>The official travel log/blog of the Alexiev family</description>
	<lastBuildDate>Sun, 31 Jan 2021 23:15:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://alexievarts.com/wp-content/uploads/2017/06/cropped-AlexievArts-32x32.png</url>
	<title>create react app Archives - Alexiev Arts</title>
	<link>https://alexievarts.com/tag/create-react-app/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Dynamic meta tags with Create React App, Handlebars, and no Server-Side Rendering</title>
		<link>https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/</link>
					<comments>https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/#respond</comments>
		
		<dc:creator><![CDATA[Akrion]]></dc:creator>
		<pubDate>Thu, 15 Aug 2019 06:32:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[cra]]></category>
		<category><![CDATA[create react app]]></category>
		<category><![CDATA[dynamic meta]]></category>
		<category><![CDATA[handlebars]]></category>
		<category><![CDATA[react]]></category>
		<guid isPermaLink="false">https://alexievarts.com/?p=5704</guid>

					<description><![CDATA[<p>Create React App (CRA) offers quite a few advantages when it comes to mocking up quickly a react web application. One of the disadvantages however is that if you want to have your open graph and meta tags populated dynamically some sort of server-side rendering approach is usually recommended. That however is not always the [&#8230;]</p>
<p>The post <a href="https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/">Dynamic meta tags with Create React App, Handlebars, and no Server-Side Rendering</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">Create React App (<a href="https://create-react-app.dev/docs/getting-started" target="_blank" rel="noreferrer noopener">CRA</a>) offers quite a few advantages when it comes to mocking up quickly a react web application. One of the disadvantages however is that if you want to have your <a href="https://en.wikipedia.org/wiki/Facebook_Platform#Open_Graph_protocol" target="_blank" rel="noreferrer noopener">open graph</a> and meta tags populated dynamically some sort of server-side rendering approach is usually recommended. That however is not always the desired route nor the most trivial to set up. </p>



<p>In this article, we would explore a solution where we would make our <code><strong>index.html</strong></code> a handlebars template and hydrate it on the client site without SSR (Server-Side Rendering). This approach would use the <code>npm <strong>scripts</strong></code> section of our <strong>package.json</strong> where we would replace the <code><strong>start</strong></code> and add <code><strong>prebuild</strong></code> stages with simple bash scripts. That way by doing <code><strong>npm start</strong></code> to start our app we would be hydrating and creating the <code><strong>index.html</strong></code> at run and build time. Also, this approach would allow for multiple environments and instances configuration. You would be able to dynamically hydrate your index for development vs. production build or <strong>siteA</strong> vs. <strong>siteB</strong> instance by simply providing create react app with a few <a href="https://create-react-app.dev/docs/adding-custom-environment-variables" target="_blank" rel="noreferrer noopener">environment variables</a>. </p>



<p><strong>TLDR</strong>: Working version of the CRA below can be found <a href="https://repl.it/@akrion/Dynamic-Meta" target="_blank" rel="noreferrer noopener">on Repl.it</a>. Fork it to run the npm scripts etc.</p>



<h2 class="wp-block-heading">Requirements:</h2>



<ul class="wp-block-list"><li><a href="https://nodejs.org/en/" target="_blank" rel="noreferrer noopener">Nodejs</a>  version 8.10 or above</li><li>npm version 5.6 or above</li></ul>



<h2 class="wp-block-heading">Setting up our React App</h2>



<p>So lets start with creating our CRA first which we would name <code><strong>dynamic-meta</strong></code> with:</p>



<pre class="wp-block-code"><code><strong>npx</strong> create-react-app dynamic-meta</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p><code>npx</code>&nbsp;on the first line is not a typo — it’s a&nbsp;<a href="https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b" target="_blank" rel="noreferrer noopener">package runner tool that comes with npm 5.2+</a></p></blockquote>



<p>Next, let&#8217;s add the <a href="https://www.npmjs.com/package/hbs-cli" target="_blank" rel="noreferrer noopener">handlebars CLI</a> package called <code><strong>hbs-cli</strong></code> and save it to our <code><strong>package.json</strong></code> file as a dependency:</p>



<pre class="wp-block-code"><code><strong>npm</strong> i hbs-cli -s</code></pre>



<p>We need the <code><strong>hbs-cli</strong></code> in order to run handlebars via the shell script which we would place in our <code>package.json scripts</code> section. </p>



<p>At this point, we have all the needed packages from npm to make this work. Next, let&#8217;s setup a few more files and folders for organization purposes. Let&#8217;s move the <code><strong>index.html</strong></code> from the <strong>public</strong> folder to a folder in the root called <code><strong>template</strong></code> and rename it to <code><strong>index.hbs</strong></code>. This would be our template which would be hydrated to produce the final <code>index.html</code> in the public folder. We would also add some handlebars variables and clean up some of the comments added by CRA. So the end result is something like this:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="%PUBLIC_URL%/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="<strong>{{{TITLE}}}</strong>"/&gt;
    &lt;meta property="og:description" content="<strong>{{{DESCRIPTION}}}</strong>"/&gt;
    &lt;link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /&gt;
    &lt;link rel="manifest" href="%PUBLIC_URL%/manifest.json" /&gt;
    &lt;title&gt;<strong>{{{TITLE}}}</strong>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>



<p>You can already see what we would be replacing in the index template. All the handlebars variables shown above would be hydrated via json files at start/build time. To learn more about handlebars <a href="https://handlebarsjs.com/guide/" target="_blank" rel="noreferrer noopener">click here</a>.</p>



<p>Now we would assume that we have few environments for our application and few instances as well. For example, we will have a development environment and a production one and in each of those, we might have different API and other keys that we might want to use. You might have a sandbox API key for a 3rd party integration in development and another production version for your production environment. Also, each one of the different instances might have a different <strong>favicon.ico</strong> and <strong>manifest.json</strong> as well. What about the app logo? </p>



<p>So in order to support all those we would simply create another folder in the root and call it <strong>sites</strong>. In that folder, we would have <strong>sub-folders</strong> with the name of our instances. For this example, we would use <code><strong>siteA</strong></code> and <code><strong>siteB</strong></code>. And since we are creating folders, let&#8217;s create another one called <strong>scripts</strong> in the root folder. </p>



<p>At this point, our app tree looks like this:</p>



<pre class="wp-block-code"><code><strong>root</strong>
|
└-- <strong>public</strong>        // CRA default public folder
└-- <strong>scripts</strong>       // Our <code>start</code> and <code>prebuild</code> scripts reside here
└-- <strong>sites</strong>         // To keep our instance folders organized
|   |
|   └-- <strong>siteA</strong>     // Instance folder A
|   └-- <strong>siteB</strong>     // Instance folder B
└-- <strong>src</strong>           // CRA default source folder
└-- <strong>template</strong>      // Where our index.hbs resides
    |
    └-- <strong>index.hbs</strong> // Our handlebars template file
</code></pre>



<p>Since each instance of our site would be different in terms of look and feel we would copy favicon.ico, logo files, and manifest.json to each of the instance folders and remove them from the public folder. Our <strong>public</strong> folder should contain only the <code><strong>rebots.txt</strong></code> file generated by the CRA at this point. We would copy all the instance files from the instance folder to the public folder at start &amp; build time. We will also add an entry to our <code><strong>.gitignore</strong></code> file to ignore all files in the public folder except the robots.txt one later.</p>



<h2 class="wp-block-heading">The configuration JSON files</h2>



<p>We would also want each site instance to have its own images/title/description/API Keys etc. So let&#8217;s start with what would be common between all the <strong>siteA</strong> environments. <strong>Title</strong> and <strong>Description</strong> sound like good candidates here. Let&#8217;s create a <strong>default.json file that</strong> would be always used by handlebars when we want to hydrate our <strong>index.hbs</strong>.  For <strong>siteA</strong> we would have:</p>



<pre class="wp-block-code"><code>{
  "TITLE": "SITE A",
  "DESCRIPTION": "SITE A Description"
}</code></pre>



<p>You <strong>would have the same name file in the siteB folder with different values for the TITLE and DESCRIPTION.</strong> </p>



<p>Ok we are almost there. The only thing missing is the actual scripts to &#8220;glue&#8221; together everything. </p>



<h2 class="wp-block-heading">The Scripts</h2>



<p>If you try to run our app at its current state nothing good would happen since we have <strong>no index.html</strong> at all in our public folder. We need to actually generate one. To do this let&#8217;s set up our scripts in our <strong>package.json</strong> first:</p>



<pre class="wp-block-code"><code>"scripts": {
<strong>    "start": "bash scripts/start.sh",
    "prebuild": "bash scripts/prebuild.sh",</strong>
    <strong>"build": "react-scripts build",</strong>
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },</code></pre>



<p>Next, let&#8217;s create the <strong>prebuild.sh</strong> file in the <strong>scripts folder</strong>. We start with that one since the <strong>start.sh</strong> would be relying on the <strong>prebuild.sh</strong>. Here is what the <strong>prebuild.sh would look like</strong>:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env bash

# Parameters
<strong>ENV=${REACT_APP_NODE_ENV:-development}
INSTANCE=${REACT_APP_NODE_APP_INSTANCE:-siteA}
</strong>
# Folders
<strong>PUB="public"
SITES="sites"</strong>

# Files containing the handlebars variables
<strong>DEFAULT_FILE=${PUB}/default.json
ENV_FILE=${PUB}/${ENV}.json</strong>

# Template files as parameters to the CLI command
<strong>PARAMS="-D ${DEFAULT_FILE}"</strong>

<strong>echo "ENV: $ENV"
echo "INSTANCE: $INSTANCE"
echo</strong>

# Copy all instance files into the public web folder
<strong>&#91; -d ${SITES}/${INSTANCE} ] &amp;&amp; command cp ${SITES}/${INSTANCE}/* ${PUB}</strong>

# Only continue if we have default template variables file
<strong>if &#91; -f ${DEFAULT_FILE} ]
then</strong>
  # Concatenate env variables file to the data parameters variable
  <strong>&#91; -f ${ENV_FILE} ] &amp;&amp; PARAMS="${PARAMS} -D ${ENV_FILE}"</strong>

  # Run the CLI for handlebars to hydrate the template with the data files
  <strong>command npx hbs ${PARAMS} template/index.hbs -o ${PUB}</strong>

  # Remove the copied template json files except manifest.json
  <strong>command find ${PUB}/*.json ! -name manifest.json | xargs rm</strong>
<strong>fi</strong>

<strong>echo "┌-----------------┐"
echo "| Pre-Build Done! |"
echo "└-----------------┘"</strong></code></pre>



<p>Now we would not go into too many details of what the shell script above does (there are comments on every line) but here are few pointers. The first and most important thing to mention here is the parameters being read in ENV and INSTANCE variables. If any is provided then we would use those but if not we would default to <code><strong>development</strong></code> environment and <code><strong>siteA</strong></code> instance.</p>



<p>Note that we use the <code><strong>command</strong></code> prefix in order to make sure we <a href="https://askubuntu.com/questions/512770/what-is-use-of-command-command" target="_blank" rel="noreferrer noopener">avoid any aliases being used</a>. For example, if the alias of <strong>cp -i</strong> is registered for the <strong>cp</strong> command the script would have different behavior. Another important thing to more here is the use of <code><strong>npx hbs</strong></code> in order to hydrate our <strong>index.hbs</strong> template and produce the <strong>index.html</strong> file. Handlebars by default outputs HTML so we only specify the output folder with the <strong>-o parameter</strong>.</p>



<p>Next lets setup our final script file &#8211; the <strong>start.sh</strong>:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env bash

<strong>export REACT_APP_NODE_ENV="${REACT_APP_NODE_ENV:-development}"</strong>
<strong>export REACT_APP_NODE_APP_INSTANCE="${REACT_APP_NODE_APP_INSTANCE:-siteA}"</strong>

# Run the prebuild with the exported above ENV variables
<strong>bash scripts/prebuild.sh</strong>

# Start the app
<strong>npx react-scripts start</strong></code></pre>



<p>As you can see the only purpose of the <strong>start.sh </strong>is to export the REACT_APP variables so they are accessible to the <strong>prebuild.sh</strong>  file. After that, it simply start the app via the <strong>react-scripts start command</strong>. Note also that it defaults the <strong>REACT_APP_NODE_ENV</strong> to <code><strong>development</strong></code> and <strong>REACT_APP_NODE_APP_INSTANCE</strong> to <code><strong>siteA</strong></code>. This is for convenience purposes since we do not want to always specify the CRA environment variables to start our app. This way <code><strong>npm start</strong></code> would start the <strong><code>development</code> siteA</strong>.</p>



<h2 class="wp-block-heading">Wrapping things up</h2>



<p>So if you <strong>start</strong> our app right now with <strong>npm start</strong> &#8230; this is what we should see in the terminal:</p>



<pre class="wp-block-code"><code>ENV: development
INSTANCE: siteA

Wrote /&lt;PATH TO YOUR APP&gt;/dynamic-meta/public/index.html from template/index.hbs
┌-----------------┐
| Pre-Build Done! |
└-----------------┘</code></pre>



<p>Opening the page source of the dynamically created <strong>index.html </strong>in the <strong>public folder</strong> gives us:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="<strong>SITE A</strong>"/&gt;
    &lt;meta property="og:description" content="<strong>SITE A Description</strong>"/&gt;
    &lt;link rel="apple-touch-icon" href="/logo192.png" /&gt;
    &lt;link rel="manifest" href="/manifest.json" /&gt;
    &lt;title&gt;<strong>SITE A</strong>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;script src="/static/js/bundle.js"&gt;&lt;/script&gt;&lt;script src="/static/js/0.chunk.js"&gt;&lt;/script&gt;&lt;script src="/static/js/main.chunk.js"&gt;&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</code></pre>



<p>As you can see we have our handlebars variables hydrated. Now lets try passing a different instance with:</p>



<pre class="wp-block-code"><code>R<strong>EACT_APP_NODE_APP_INSTANCE=siteB</strong> npm start</code></pre>



<p>We would get as we would expect the <strong>siteB</strong> meta title and description:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="<strong>SITE B</strong>"/&gt;
    &lt;meta property="og:description" content="<strong>SITE B Description</strong>"/&gt;
    &lt;link rel="apple-touch-icon" href="/logo192.png" /&gt;
    &lt;link rel="manifest" href="/manifest.json" /&gt;
    &lt;title&gt;<strong>SITE B</strong>&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;script src="/static/js/bundle.js"&gt;&lt;/script&gt;&lt;script src="/static/js/0.chunk.js"&gt;&lt;/script&gt;&lt;script src="/static/js/main.chunk.js"&gt;&lt;/script&gt;&lt;/body&gt;
&lt;/html&gt;</code></pre>



<h2 class="wp-block-heading">More than just meta tags</h2>



<p>Last but not least what about different values that we might have for environments like development or production?  Let&#8217;s say we have a 3rd party app integration like google analytics or similar that has different keys for the different environments. How would we solve that with the approach above?</p>



<p>We simply add them in the <code><strong>index.hbs</strong></code> with handlebars <strong>if</strong> condition and we add the environment json files. <strong>Our prebuild script already accounts for that</strong>. So let&#8217;s add <strong>development.json</strong> and <strong>production.json</strong> in the <strong>siteA</strong> and <strong>siteB</strong> site folders. In each let&#8217;s add a prop with the name <strong>APP_ID</strong>. For example, this would be our <strong>sites/siteA/development.json</strong>:</p>



<pre class="wp-block-code"><code>{
  "APP_ID": "DEV SITE A"
}</code></pre>



<p>and this <strong>sites/siteA/production.json</strong>:</p>



<pre class="wp-block-code"><code>{
  "APP_ID": "PROD SITE A"
}</code></pre>



<p>Now lets add in the <strong>index.hbs</strong> template:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8" /&gt;
    &lt;link rel="icon" href="%PUBLIC_URL%/favicon.ico" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
    &lt;meta name="theme-color" content="#000000" /&gt;
    &lt;meta property="og:title" content="{{{TITLE}}}"/&gt;
    &lt;meta property="og:description" content="{{{DESCRIPTION}}}"/&gt;
    &lt;meta name="description" content="{{{DESCRIPTION}}}"/&gt;
    &lt;link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /&gt;
    &lt;link rel="manifest" href="%PUBLIC_URL%/manifest.json" /&gt;
    &lt;title&gt;{{{TITLE}}}&lt;/title&gt;
<strong>    &lt;script type="text/javascript"&gt;
      {{# if APP_ID}}window.APP_ID='{{APP_ID}}';{{/if}}
      if (window.APP_ID) {
        alert(`APP_ID: ${window.APP_ID}`)
      }
    &lt;/script&gt;</strong>
  &lt;/head&gt;
  &lt;body&gt;
    &lt;noscript&gt;You need to enable JavaScript to run this app.&lt;/noscript&gt;
    &lt;div id="root"&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>



<p>We simply use handlebars if condition which says if we have as a variable <strong>APP_ID</strong> then write the text <strong>window.APP_ID='{{{APP_ID}}&#8217;</strong>  and replace the APP_ID with the value. Then we check if <strong>window.APP_ID</strong> exists and if so we alert it. So if we run this with the default <code><strong>npm start</strong></code> we would see the alert <strong>DEV SITE A</strong> since we have an entry for the APP_ID in our <strong><code>siteA</code> development.json</strong> file.</p>



<p>Now lets run the production one with:</p>



<pre class="wp-block-code"><code><strong>REACT_APP_NODE_ENV=production REACT_APP_NODE_APP_INSTANCE=siteA</strong> npm start</code></pre>



<p>Now we would be using the the <strong>APP_ID</strong> from the <strong>production.json</strong> file and we would get <strong>PROD SITE A</strong> alert.</p>



<h2 class="wp-block-heading">What about build time?</h2>



<p>If you would like to crate a build for the default <code><strong>siteA</strong></code> instance and the default <code><strong>development</strong></code> environment when you simply run: </p>



<pre class="wp-block-code"><code>npm <strong>run build</strong></code></pre>



<p>To run a <strong>production</strong> build for <strong>siteB</strong> you would run:</p>



<pre class="wp-block-code"><code>REACT_APP_NODE_ENV=<strong>production</strong> REACT_APP_NODE_APP_INSTANCE=<strong>siteB</strong> npm run build</code></pre>



<p>The cool thing is that we have hooked our dynamic index.html creation at the prebuild time so the actual build would already have the <strong>hydrated index.html</strong> from the <strong>index.hbs</strong> and would then go through the create react app react-scripts pipeline to create the final create react app build.</p>



<h2 class="wp-block-heading">Repl.it</h2>



<p>If you would like to play with the code for this and see the actual results from the create react app just go to <a href="https://repl.it/@akrion/Dynamic-Meta" target="_blank" rel="noreferrer noopener"><strong>this link</strong></a>. Then click on the <strong>Run</strong> button to start the default build. You can also then use the Repl.it console to execute the different <strong>npm start</strong> commands we mentioned above where you would pass the REACT_APP_NODE_ENV and the REACT_APP_NODE_APP_INSTANCE parameters.</p>



<h2 class="wp-block-heading">Other Options</h2>



<p>You can achieve a <strong>similar result</strong> without the use of the <code><strong>hbs-cli</strong></code> package and only with shell. For that, you can use the <a href="https://github.com/tests-always-included/mo" target="_blank" rel="noreferrer noopener">Mustache templates in bash</a> or <strong>mo</strong> for short and call that instead of <strong>hbs-cli</strong> in your <strong>prebuild.sh</strong> script. You might have to change the parameters passed to <strong>mo</strong> slightly but other than that the rest would remain the same.</p>
<p>The post <a href="https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/">Dynamic meta tags with Create React App, Handlebars, and no Server-Side Rendering</a> appeared first on <a href="https://alexievarts.com">Alexiev Arts</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://alexievarts.com/technology/create-react-app-dynamic-head-meta-elements-with-handlebars-and-no-ssr/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
