<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[raslan.dev]]></title><description><![CDATA[raslan.dev]]></description><link>https://blog.raslan.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 10:39:11 GMT</lastBuildDate><atom:link href="https://blog.raslan.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Announcing Throwaway v4]]></title><description><![CDATA[What is Throwaway anyway?
Whether you're discovering Throwaway for the first time or simply curious about its capabilities, this Chrome extension is designed to streamline authentication and form filling—ideal for both privacy protection and form tes...]]></description><link>https://blog.raslan.dev/announcing-throwaway-v4</link><guid isPermaLink="true">https://blog.raslan.dev/announcing-throwaway-v4</guid><category><![CDATA[Web Development]]></category><category><![CDATA[extensions]]></category><category><![CDATA[chrome extension]]></category><category><![CDATA[automation]]></category><category><![CDATA[QA]]></category><category><![CDATA[privacy]]></category><dc:creator><![CDATA[Ali Raslan]]></dc:creator><pubDate>Fri, 23 Aug 2024 17:17:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724431055245/caa437d0-acac-49bb-9102-e050d9eccfa9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-what-is-throwaway-anyway">What is Throwaway anyway?</h3>
<p>Whether you're discovering Throwaway for the first time or simply curious about its capabilities, this Chrome extension is designed to streamline authentication and form filling—ideal for both privacy protection and form testing.</p>
<p>If you need to sign up to websites that don't deserve your data or you're testing a form and you'd like to be able to iterate fast and without spamming your own email, Throwaway is for you.</p>
<p>It's completely free, open source, and respects your privacy with zero data collection and no registration or login required. Throwaway exists to make your life easier, not to add to the list of accounts or data-harvesting platforms you worry about day to day.</p>
<p>Throwaway is available <a target="_blank" href="https://chromewebstore.google.com/detail/throwaway/ckchejeejieimhknlpiipmmjcapomggi">Here at the Chrome Store.</a></p>
<p>Below, I’ll cover all the features, including what's new, so here’s everything Throwaway can do today:</p>
<h2 id="heading-key-features-of-throwaway-v4">Key Features of Throwaway v4</h2>
<p>v4 has been fully rewritten and redesigned from the ground up, here's some highlights</p>
<h3 id="heading-the-new-tabs">The new Tabs</h3>
<p>You've got the Identity tab, this one includes all your "fillable" data as well as the ability to generate a new identity with a fresh email</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724338506946/7f6f138d-1dd4-4dde-90d3-e0e4f35d3460.png" alt class="image--center mx-auto" /></p>
<p>The Email tab is your inbox, refreshes automatically every 3 seconds, you can switch between the latest 5 email addresses freely.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724338545566/df6e8766-38b4-416b-91d9-8a46ad3d1cde.png" alt class="image--center mx-auto" /></p>
<p>And new in this update is the Configuration tab! This allows you to tune various settings and even add your own custom fields for the autofill (we'll dive deeper into each these below)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724338593204/ca69bae3-123f-45bb-8fc0-b2d1f3f5db2a.png" alt class="image--center mx-auto" /></p>
<p>There's a light mode now! Here's a screenshot, available in the configuration tab, dark is still default.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724338334726/0a49014f-d359-409d-ba0c-84b8b8656e68.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-the-right-click">The Right Click</h3>
<p>Throwaway v3 introduced the "Fill with Throwaway" context menu item where you can right click anywhere in a webpage and then:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724339047842/fe374bfc-6939-4963-b308-98407e6298a6.png" alt class="image--center mx-auto" /></p>
<p>to fill all the content.</p>
<p>In the latest version, this can even detect and fill one time passcodes from the latest email directly without even opening the extension:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724340586616/1f686d6c-3112-4305-809c-c1aea67d557e.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-you-can-now-modify-identity-fields">You Can Now Modify Identity Fields</h3>
<p>A feature in the Configuration tab but it deserves its own section for clarity. You can now add custom fields to Throwaway (finally, this has been the most requested feature forever really), if you head to the Configuration tab you can now toggle it on and click "Modify" to add your fields. These can then be viewed in the "Custom Fields" section in the Identity tab.</p>
<p>These are treated as first class data when filling, you can use the input's label or any of its attributes if you know them ahead of time, you can even <strong><em>guess</em></strong>! (and Throwaway will do its best to match it to what's on the page)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724339960988/87a90d37-ca9d-458f-aaf0-299168472210.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-tuning-generated-identities-with-configuration">Tuning Generated Identities with "Configuration"</h3>
<p>We've got a lot to cover here so each feature will have a short demo.</p>
<h4 id="heading-address-country">Address Country</h4>
<p>Generate example addresses and financial data, choosing from three regions: the United States, Spain (EU), and the United Kingdom (non-US/EU).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724339503812/3e2096b4-dc30-46e3-a086-bab19d73714c.gif" alt class="image--center mx-auto" /></p>
<h4 id="heading-testing-cards">Testing Cards</h4>
<p>Five built-in presets for popular providers like <a target="_blank" href="https://docs.stripe.com/testing#cards">Stripe's dev cards</a>. Useful for when developing a payment form using one of these providers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724339697021/a1b2c276-601b-4c9c-a4af-0e6747614894.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-multiple-email-inboxes">Multiple Email Inboxes</h3>
<p>You can now switch between the latest 5 email addresses freely! No more pressing "New Identity" and losing access to those verification emails you wanted to screenshot for your QA ticket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1724340108808/340bfe42-8586-4c63-a452-de09c22042b4.gif" alt class="image--center mx-auto" /></p>
<h3 id="heading-context-menus">Context Menus</h3>
<p>There are now right click menus for the Credit Card and for each email preview to allow copying, downloading and other nifty things. Try right clicking!</p>
<h3 id="heading-filling-enhancements">Filling Enhancements</h3>
<p>The filling logic is now smarter, allowing even more stubborn fields to be filled.</p>
<p>Label based filling is now supported for fields with no identifiers on the input tag, of course this feature also supports the new custom fields as well so go crazy with that.</p>
<p>All autofilling is now case insensitive, this may or may not have a positive impact, it may have a configuration toggle later. <strong>(Please reach out if it or anything else are working weirdly for you.)</strong></p>
]]></content:encoded></item><item><title><![CDATA[Build a Next App with a full GraphQL API from just a JSON or CSV file]]></title><description><![CDATA[Introduction
In this guide, we'll be using a JSON or CSV file with some data in it to build a fully featured GraphQL API inside a NextJS application.
For this to work, we'll need some tools, here are links to all the tools used in this guide if you'd...]]></description><link>https://blog.raslan.dev/build-a-next-app-with-a-full-graphql-api-from-just-a-json-or-csv-file</link><guid isPermaLink="true">https://blog.raslan.dev/build-a-next-app-with-a-full-graphql-api-from-just-a-json-or-csv-file</guid><category><![CDATA[GraphQL]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[prisma]]></category><dc:creator><![CDATA[Ali Raslan]]></dc:creator><pubDate>Tue, 24 Jan 2023 11:33:08 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In this guide, we'll be using a JSON or CSV file with some data in it to build a fully featured GraphQL API inside a NextJS application.</p>
<p>For this to work, we'll need some tools, here are links to all the tools used in this guide if you'd like to check any of them out or potentially explore replacements:</p>
<ul>
<li><p><a target="_blank" href="https://prisma.io">Prisma</a> The database connector where all the magic happens</p>
</li>
<li><p><a target="_blank" href="https://prisma.typegraphql.com/">Typegraphql-Prisma</a> To generate the TypeGraphQL schema for the Apollo server from Prisma</p>
</li>
<li><p><a target="_blank" href="https://typegraphql.com/">TypeGraphQL</a></p>
</li>
<li><p><a target="_blank" href="https://www.apollographql.com/">Apollo Server</a></p>
</li>
<li><p><a target="_blank" href="https://the-guild.dev/graphql/codegen">graphql-code-generator</a> To build the types for the frontend</p>
</li>
<li><p><a target="_blank" href="https://nextjs.org/">Next</a> The fullstack framework we'll be using</p>
</li>
<li><p><a target="_blank" href="https://reactjs.org">React</a> The frontend part</p>
</li>
</ul>
<h2 id="heading-create-a-mongodb-database-and-add-your-data-skip-if-you-already-have-a-mongodb-database-with-data-in-it">Create a MongoDB database and add your data (skip if you already have a MongoDB database with data in it)</h2>
<p>Head to <a target="_blank" href="http://mongodb.com">mongodb.com</a> and sign up for a free Atlas account or set up mongodb locally</p>
<p>Create your project</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213875987-e529e32e-dac1-42a2-b2ad-b2fafbd0947d.png" alt="image" /></p>
<p>Create a cluster, select <code>SHARED</code> for the free tier.</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876016-cc50b07b-749a-4c5b-8b3c-b82697148727.png" alt="image" /></p>
<p>Create your user and add your IP address to the list of allowed IP addresses (or 0.0.0.0 to allow any connection).</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876088-1b4d42db-f6e1-4609-a6a2-563035cc97f9.png" alt="image" /></p>
<p>Press <code>connect</code> on your cluster on <a target="_blank" href="http://mongodb.com">mongodb.com</a></p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876204-558c3d87-9c95-4ed4-8cc0-cb2b21c9043f.png" alt="image" /></p>
<p>Click on Compass</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876216-82bfb6ce-b0e4-4ccc-834d-efcda13a4d5c.png" alt="image" /></p>
<p>Download Compass if you don't have it, and copy the connection string</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876259-1dc4bb37-f9c5-4692-87dc-cdc041297964.png" alt="image" /></p>
<p>Paste the connection string into Compass, replacing with the password for the database user you created earlier and press connect</p>
<p>Click databases</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876355-b0fccd85-7187-4038-99ef-02ec163c3f03.png" alt="image" /></p>
<p>Click create</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876371-56f39960-4660-4b44-ba84-c6b1a6359837.png" alt="image" /></p>
<p>In the database name and collection name fields, describe the data type your database will contain, for example a database of football players could be called <code>football_players</code> or <code>players</code></p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876423-ef89a240-8830-4b19-9792-4ee2e6c707bd.png" alt="image" /></p>
<p>Once the database is created, click on it</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876476-edb8e9e0-8b2d-4403-85f6-07120e4b74b1.png" alt="image" /></p>
<p>Click the collection</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876501-c3770aeb-8c53-4eae-a662-0acf44a03539.png" alt="image" /></p>
<p>You can now upload your JSON or CSV file to the database to fill it</p>
<p><img src="https://user-images.githubusercontent.com/24810123/213876522-74caf063-cd06-440a-a6cb-f1710858c457.png" alt="image" /></p>
<p>We now have a database with the data we need, you can close Compass.</p>
<h2 id="heading-create-a-nextjs-app-with-typescript">Create a NextJS app with TypeScript</h2>
<h4 id="heading-answer-the-questions-as-you-like-but-when-asked">Answer the questions as you like but when asked</h4>
<p>'if you want to use the new <code>/app</code> directory' no</p>
<p>'if you want to use <code>src</code> directory' no</p>
<pre><code>yarn create next-app --typescript
</code></pre><h2 id="heading-install-dependencies">Install dependencies</h2>
<pre><code>yarn add prisma typegraphql-prisma -D

yarn add @apollo/server @<span class="hljs-keyword">as</span>-integrations/next @prisma/client graphql <span class="hljs-class"><span class="hljs-keyword">class</span>-<span class="hljs-title">validator</span> <span class="hljs-title">type</span>-<span class="hljs-title">graphql</span>@<span class="hljs-title">next</span> <span class="hljs-title">reflect</span>-<span class="hljs-title">metadata</span> <span class="hljs-title">graphql</span>-<span class="hljs-title">scalars</span> <span class="hljs-title">graphql</span>-<span class="hljs-title">fields</span> @<span class="hljs-title">types</span>/<span class="hljs-title">graphql</span>-<span class="hljs-title">fields</span> <span class="hljs-title">tslib</span></span>
</code></pre><h2 id="heading-initialize-prisma">Initialize prisma</h2>
<pre><code>yarn prisma init --datasource-provider mongodb
</code></pre><h2 id="heading-add-mongodb-connection-and-the-eventual-graphql-api-url-to-env">Add mongodb connection and the eventual graphql api url to .env</h2>
<pre><code>DATABASE_URL=<span class="hljs-string">"mongodb+srv://username:password@address.mongodb.net/tablename?retryWrites=true&amp;w=majority"</span>
NEXT_PUBLIC_API_URL=<span class="hljs-string">"http://localhost:3000/api/graphql"</span>
</code></pre><h2 id="heading-pull-the-database-schema-into-prisma">Pull the database schema into Prisma</h2>
<pre><code>yarn prisma db pull
</code></pre><h2 id="heading-add-generator-to-prisma">Add generator to prisma</h2>
<pre><code class="lang-prisma">generator typegraphql {
  provider = "typegraphql-prisma"
  output   = "../prisma/generated/type-graphql"
  simpleResolvers = true
}
</code></pre>
<h2 id="heading-create-tsconfigjson-or-modify-it-at-the-nextjs-root">Create tsconfig.json or modify it at the NextJS root</h2>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"allowJs"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"forceConsistentCasingInFileNames"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"noEmit"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"moduleResolution"</span>: <span class="hljs-string">"node"</span>,
    <span class="hljs-attr">"resolveJsonModule"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"isolatedModules"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"jsx"</span>: <span class="hljs-string">"preserve"</span>,
    <span class="hljs-attr">"incremental"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"baseUrl"</span>: <span class="hljs-string">"."</span>,
    <span class="hljs-attr">"paths"</span>: {
      <span class="hljs-attr">"@/*"</span>: [<span class="hljs-string">"./*"</span>]
    },
    <span class="hljs-attr">"sourceMap"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"dist"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"lib"</span>: [<span class="hljs-string">"esnext"</span>, <span class="hljs-string">"esnext.asynciterable"</span>, <span class="hljs-string">"dom"</span>, <span class="hljs-string">"dom.iterable"</span>],
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"es2018"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"commonjs"</span>,
    <span class="hljs-attr">"esModuleInterop"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"emitDecoratorMetadata"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"experimentalDecorators"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"skipLibCheck"</span>: <span class="hljs-literal">true</span>
  },
  <span class="hljs-attr">"include"</span>: [<span class="hljs-string">"next-env.d.ts"</span>, <span class="hljs-string">"**/*.ts"</span>, <span class="hljs-string">"**/*.tsx"</span>],
  <span class="hljs-attr">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>]
}
</code></pre>
<h2 id="heading-generate-the-prisma-schema">Generate the prisma schema</h2>
<pre><code>yarn prisma generate
</code></pre><h2 id="heading-create-pagesapigraphqlts">Create /pages/api/graphql.ts</h2>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> <span class="hljs-string">'reflect-metadata'</span>;
<span class="hljs-keyword">import</span> { resolvers } <span class="hljs-keyword">from</span> <span class="hljs-string">'prisma/generated/type-graphql'</span>;
<span class="hljs-keyword">import</span> { PrismaClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@prisma/client'</span>;
<span class="hljs-keyword">import</span> { ApolloServer } <span class="hljs-keyword">from</span> <span class="hljs-string">'@apollo/server'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> tq <span class="hljs-keyword">from</span> <span class="hljs-string">'type-graphql'</span>;
<span class="hljs-keyword">import</span> { startServerAndCreateNextHandler } <span class="hljs-keyword">from</span> <span class="hljs-string">'@as-integrations/next'</span>;

<span class="hljs-keyword">const</span> prisma = <span class="hljs-keyword">new</span> PrismaClient();

<span class="hljs-keyword">const</span> schema = tq.buildSchemaSync({
  resolvers,
  validate: <span class="hljs-literal">false</span>,
});

<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({ schema });

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> startServerAndCreateNextHandler(server, {
  context: <span class="hljs-keyword">async</span> () =&gt; ({ prisma }),
});
</code></pre>
<h2 id="heading-add-this-line-to-the-top-of-apptsx">Add this line to the top of <code>_app.tsx</code></h2>
<pre><code class="lang-tsx">import 'reflect-metadata';
</code></pre>
<h2 id="heading-start-your-next-app">Start your Next app</h2>
<pre><code class="lang-plaintext">yarn dev
</code></pre>
<p>Access the server at <a target="_blank" href="http://localhost:3000/api/graphql">http://localhost:3000/api/graphql</a></p>
<h2 id="heading-enabling-cors-to-use-outside-vercel">Enabling CORS to use outside Vercel</h2>
<p>Add the following to <code>next.config.js</code>.</p>
<pre><code class="lang-js"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('next').NextConfig}</span> </span>*/</span>
<span class="hljs-keyword">const</span> nextConfig = {
  <span class="hljs-attr">reactStrictMode</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-keyword">async</span> headers() {
    <span class="hljs-keyword">return</span> [
      {
        <span class="hljs-attr">source</span>: <span class="hljs-string">'/api/:path*'</span>,
        <span class="hljs-attr">headers</span>: [
          { <span class="hljs-attr">key</span>: <span class="hljs-string">'Access-Control-Allow-Credentials'</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">'true'</span> },
          { <span class="hljs-attr">key</span>: <span class="hljs-string">'Access-Control-Allow-Origin'</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">'*'</span> },
          {
            <span class="hljs-attr">key</span>: <span class="hljs-string">'Access-Control-Allow-Methods'</span>,
            <span class="hljs-attr">value</span>: <span class="hljs-string">'GET,OPTIONS,PATCH,DELETE,POST,PUT'</span>,
          },
          {
            <span class="hljs-attr">key</span>: <span class="hljs-string">'Access-Control-Allow-Headers'</span>,
            <span class="hljs-attr">value</span>:
              <span class="hljs-string">'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'</span>,
          },
        ],
      },
    ];
  },
};

<span class="hljs-built_in">module</span>.exports = nextConfig;
</code></pre>
<h2 id="heading-automatically-generate-types-for-the-client">Automatically generate types for the client</h2>
<p>Install graphql-code-generator</p>
<pre><code>yarn add -D ts-node @graphql-codegen/cli @graphql-codegen/client-preset
</code></pre><p>Create <code>codegen.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { CodegenConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">'@graphql-codegen/cli'</span>;

<span class="hljs-keyword">const</span> config: CodegenConfig = {
  schema: <span class="hljs-string">"http://localhost:3000/api/graphql"</span>,
  documents: [<span class="hljs-string">'pages/**/*.tsx'</span>],
  ignoreNoDocuments: <span class="hljs-literal">true</span>, <span class="hljs-comment">// for better experience with the watcher</span>
  generates: {
    <span class="hljs-string">'./gql/'</span>: {
      preset: <span class="hljs-string">'client'</span>,
      plugins: [],
    },
  },
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> config;
</code></pre>
<p>Install concurrently</p>
<pre><code>yarn add -D concurrently
</code></pre><p>Modify your <code>dev</code> script in <code>package.json</code></p>
<pre><code><span class="hljs-string">"dev"</span>: <span class="hljs-string">"concurrently \"yarn next dev\" \"yarn graphql-codegen --watch\""</span>,
</code></pre><h2 id="heading-communicating-with-the-api-within-next">Communicating with the API within Next</h2>
<p>Add graphql-request and react-query</p>
<pre><code>yarn add graphql-request react-query
</code></pre><p>Add React query provider and a global graphql-request client to <code>_app.tsx</code></p>
<pre><code class="lang-tsx">import 'reflect-metadata';
import type { AppProps } from 'next/app';
import { QueryClient, QueryClientProvider } from 'react-query';
import { GraphQLClient } from 'graphql-request';

const queryClient = new QueryClient();

export const client = new GraphQLClient(process.env.NEXT_PUBLIC_API_URL as string, {
  headers: {},
});

export default function App({ Component, pageProps }: AppProps) {
  return (
    &lt;QueryClientProvider client={queryClient}&gt;
      &lt;Component {...pageProps} /&gt;
    &lt;/QueryClientProvider&gt;
  );
}
</code></pre>
<p>You're now ready to use react-query with your types, here's an example <code>index.tsx</code> with a database of players</p>
<pre><code class="lang-tsx">import Head from 'next/head';
import { graphql } from 'gql';
import { useQuery } from 'react-query';
import React from 'react';
import { client } from './_app';

const findManyPlayers = graphql(`
  query FindManyPlayers($take: Int) {
    findManyPlayers(take: $take) {
      age
      hits
      name
      id
      nationality
      overall
      player_id
      position
      potential
      team
    }
  }
`);

export default function Home() {
  const { data } = useQuery(['players'], async () =&gt;
    client.request(findManyPlayers, {
      take: 5,
    })
  );
  if (!data) return &lt;&gt;&lt;/&gt;;
  return (
    &lt;&gt;
      &lt;Head&gt;
        &lt;title&gt;Create Next App&lt;/title&gt;
        &lt;meta name='description' content='Generated by create next app' /&gt;
        &lt;meta name='viewport' content='width=device-width, initial-scale=1' /&gt;
        &lt;link rel='icon' href='/favicon.ico' /&gt;
      &lt;/Head&gt;
      &lt;main&gt;
        &lt;div&gt;
          {data.findManyPlayers.map((player) =&gt; (
            &lt;React.Fragment key={player.id}&gt;
              &lt;p&gt;{player.name}&lt;/p&gt;
            &lt;/React.Fragment&gt;
          ))}
        &lt;/div&gt;
      &lt;/main&gt;
    &lt;/&gt;
  );
}
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Realistic Learning Roadmaps]]></title><description><![CDATA[It's amazing that there's no end to the number of resources available online for learning anything in the tech field, but this leads to newcomers being overwhelmed with the sheer volume of courses, videos, bootcamps, docs and interactive platforms th...]]></description><link>https://blog.raslan.dev/realistic-learning-roadmaps</link><guid isPermaLink="true">https://blog.raslan.dev/realistic-learning-roadmaps</guid><category><![CDATA[Roadmap]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[backend]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Ali Raslan]]></dc:creator><pubDate>Tue, 14 Sep 2021 00:50:21 GMT</pubDate><content:encoded><![CDATA[<p>It's amazing that there's no end to the number of resources available online for learning anything in the tech field, but this leads to newcomers being overwhelmed with the sheer volume of courses, videos, bootcamps, docs and interactive platforms that are often recommended by others already in the field.</p>
<p>A newcomer to this space will be bombarded with thousands of articles, videos and posts on platforms like YouTube, Reddit or dev.to that claim to have the "definitive roadmap".</p>
<p>To clarify, roadmaps are basically guided learning paths. Essentially a list of "learn this, then learn that, do this in the middle" that's intended to be the go-to step-by-step process for becoming a junior, mid-level or senior. In reality, these roadmaps are often either too simplistic/broad or unrealistic in the amount of time they usually claim is sufficient to complete them.</p>
<h2 id="the-burden-of-choice">The Burden of Choice</h2>
<p>Let's step back and consider why a newcomer would even need a roadmap. It should be easy to simply parse job descriptions for an idea on what technologies a position will require and just tackle those individually, but it isn't.</p>
<p>The first barrier to entry is that there's a lot of unknown pre-requisite and supplementary materials for the technologies actually listed in a given job description. These pre-requisite and companion materials are <em>branching</em> in the sense that for each library there are potentially dozens of technologies that will pair perfectly with it and are used in industry to accompany it.</p>
<p>The second barrier to entry, compounding the first, is the number of options available for an aspiring developer willing to put in the work and learn what they need to. There are simply too many libraries, frameworks, concepts, patterns, technologies and principles to learn from too many course websites, videos, articles, documentation pages, guides and open university courses. It sounds like a first world problem, but this flood of options and resources leads to every developer having a unique collection of information due to the difficult choices they have to make when learning. Effectively, every developer is different in some way unless they follow the same learning path.</p>
<p>This is where roadmaps come in. A roadmap promises some guidance on what to learn and in what order or what to focus on in order to gain the skills needed to perform the role well. In principle, there's nothing wrong with them. In practice, they leave a lot to be desired.</p>
<h2 id="the-problem-with-roadmaps">The Problem With Roadmaps</h2>
<p>A rampant issue we have is that <a target="_blank" href="https://dev.to/theme_selection/reactjs-roadmap-for-developers-2824">roadmaps often just parrot the names of libraries</a> instead of explaining <em>why</em> to learn this or that technology or this or that library. There are also <a target="_blank" href="https://dev.to/ender_minyard/full-stack-developer-s-roadmap-2k12">roadmaps that are just collections of disconnected links</a> which expect you to learn a concept from a random article or page and then jump to a <em>completely different</em> article or page to learn a <strong>related</strong> concept... This makes no sense!</p>
<p>The major issue with these library-centric roadmaps is that they encourage learning the tools instead of the concepts. This is understandable, given that the job market requires knowledge of the tools more than the concepts in many cases. But unless the learner knows this beforehand, they'll end up ignoring many of the concepts that will allow them to keep their job when the library they've learned is eventually deprecated in favor of the newer and shinier contender.</p>
<p>I see this a lot with people who learn a framework and skip learning the basics and understanding the architecture of applications, when their framework of choice is deprecated or when they're offered a new position using a different framework a lot of them struggle to make the switch. This is because after following their framework centric roadmap they became <em>framework users</em> not developers.</p>
<p>The solution for this is simple, roadmaps can be descriptive of why you need to learn something. But even when a roadmap has relevant content and descriptive resources like <a target="_blank" href="https://roadmap.sh/frontend">this one for frontend developers</a> and <a target="_blank" href="https://roadmap.sh/backend">the same one but for backend developers</a>, it can often look very intimidating to beginners. There's so many items that make little sense to a complete beginner that even with guidance on where to start, it's impossible to look at the whole list without feeling discouraged from trying. Effectively, the roadmap becomes a giant self-study syllabus without a teacher and that barrier becomes very difficult to overcome.</p>
<p>Escaping this, newcomers will end up searching for a more structured learning path to follow. This usually comes in the form of a course on an online platform like Udemy or a long video series on YouTube or structured journey-based websites like <a target="_blank" href="https://www.theodinproject.com/">The Odin Project</a>, <a target="_blank" href="https://www.freecodecamp.org/">freecodecamp</a> and <a target="_blank" href="https://fullstackopen.com/en/">Full Stack Open</a>. I have nothing against these approaches and, in fact, that's the way I'd recommend for most newcomers. These websites are mature and have started many developers' successful careers and can often be a saving grace when all the other resources are too dispersed to properly learn anything from.</p>
<p>However, there's a dangerous common issue that faces both those who follow a roadmap and those who follow guided resources: Burnout.</p>
<h2 id="burnout">Burnout</h2>
<p>By this point, you may have realized that there are indeed a lot of things you need to learn to become an effective developer. What I've discussed so far does not dispute this fact. However, it helps to outline that the real issue here isn't that you have to learn a lot, it's that you'll experience burnout.</p>
<p>I'm sure not a single developer on Earth can claim they've never felt a little burnt out while learning new things. In fact, it's so common that it's often assumed to be part of the process, that it'll happen eventually and delaying it is the best we can do. Simply put, when trying to follow a roadmap and giving yourself a strict timeline, you could often end up either covering too much in too little time or being stuck on sections that ultimately don't matter and becoming discouraged. </p>
<p>I strongly disagree with the idea that burnout is inevitable. In my own experience, I've suffered from it before, but rarely have I ever felt like I hadn't locked myself into this unhealthy pattern of not pacing myself to the point where it caused burnout in the first place. I can't stress enough that the point of a realistic roadmap and proper pacing along the way isn't to ensure that you'll learn everything, but rather to ensure that you can do that while maintaining the balance of your life and your mental health.</p>
<h2 id="building-a-realistic-roadmap">Building A Realistic Roadmap</h2>
<p>At this point, I'd like to include a disclaimer that I am not creating a roadmap for you to follow. Rather, I am going to include a set of guidelines that I've personally used to build my own roadmap to avoid burnout and make sure that I've covered the material that I need at a pace that makes me comfortable. It's also worth noting that everyone has their own method and process when learning and I do not discourage you from deviating as little or as much as you'd like from this set of guidelines.</p>
<h3 id="you-can-learn-for-free">You Can Learn For Free</h3>
<p>Because a lot of developers struggle with finding where and what to learn, a lot of people have capitalized on this by offering absurdly priced courses, resources and even <em>roadmaps costing money</em>. There's nothing wrong with paying for learning materials, but you don't <em>have</em> to.</p>
<h3 id="practice-dont-cram">Practice, Don't Cram.</h3>
<p>Development is inherently a practical field, a lot of the knowledge that we acquire is meant to be applied when developing, designing or architecting systems and applications. The approach of trying to fly through materials as fast as possible or to keep cramming until you get tired is not going to allow you to properly process this information and retain it.</p>
<p>Try to learn one "thing" at a time. If you're feeling like you haven't covered enough today, instead of covering more material, prioritize applying what you've learned. If today's thing is a new framework, try building an application with it. If it's a library, try using it in an application. Keep your learning sessions short and your practice sessions frequent to avoid forgetting things.</p>
<h3 id="read-job-descriptions">Read Job Descriptions</h3>
<p>The new and shiny libraries of the day are often overrepresented in online material; from articles to videos and pages dedicated to this new tech, it can be easy to forget that companies still use <em>stable</em> and <em>battle-tested</em> tech. This can so extreme as to be old and deprecated, but remember that you're focusing on the concepts and not the specific libraries.</p>
<p>Job descriptions usually include the main technology that you'll be working with day to day, other supplemental technologies may or may not be mentioned as well. Reading these allows you to know what to keep an eye on for your desired position, but keep in mind you shouldn't take it as gospel that what's required in this job description will be what's required in the same role at a different company. Be mindful of what's being used in the industry to guide your learning process, but do not let it overwhelm your choices.</p>
<h3 id="build-meaningful-projects">Build Meaningful Projects</h3>
<p>This is different from practicing in the sense that I'm not talking about building a little project to try out a library or a framework, but rather building a project to allow you to run into real world issues that you would <em>only</em> face when building an application or system.</p>
<p>If you can avoid template project tutorials like "How to build a Facebook Clone", I strongly suggest you stay away from them. These projects, unless you wildly innovate on them, act as a placeholder on your resume and portfolio. Not to mention that, usually, you end up making no decisions of your own for the application.</p>
<p>Coming up with project ideas is difficult, but you don't need to build something complicated. My approach is to build things that I'd like to use or have like tools or to build exploratory projects or working with weird and interesting libraries.</p>
<h3 id="join-the-community">Join The Community</h3>
<p>Whether you'd like to know about new and interesting technologies, get help from other learners, help other developers with their own learning path or even just see what other people are learning, I believe you should join online communities like Reddit's many learning-friendly subreddits such as r/learnprogramming or websites like <a target="_blank" href="https://dev.to">dev.to</a>. These positive communities encourage participation and discussion while allowing developers of all levels to ask questions and help each other.</p>
<h3 id="finally-dont-give-up">Finally, Don't Give Up</h3>
<p>The big secret to learning anything is consistency, it's more useful to study an hour a day for a year than it is to study ten hours a day for two weeks.</p>
<p>The more you learn, the more knowledgeable and confident you'll become and the more receptive you'll become to learning <em>even more</em> amazing things. The beautiful thing about becoming a developer is that one day you'll realize you know a ton of things and have a million ways to tackle the many problems that computers are built to solve.</p>
<p>You should be aware that the reason I urge you so strongly to build your own roadmap is to avoid two central issues: tutorial hell and being a master of nothing.</p>
<h2 id="lets-talk-about-tutorial-hell">Let's Talk About Tutorial Hell</h2>
<p>I'd like to shed some light on tutorial hell and why it's the reason roadmaps can be dangerous.</p>
<p>When you learn a technology without having a reason to, as you would if you were simply learning it because someone told you to, you can often miss the intended learning outcomes of this technology; or what you were supposed to learn about it beyond its syntax or its constructs. In essence, you lose out on what the point of this technology is.</p>
<p>When your only knowledge of a technology is its syntax or usage, you can very easily fall into tutorial hell: where the only way you can make anything using this technology <em>that you know</em> is to follow a guided tutorial teaching you how to make something with it. </p>
<p>I hinted at this earlier when I urged you to avoid "How to build a Facebook Clone"-type tutorials, these are purpose built for padding your GitHub and your resume with "projects" where in reality you know nothing about the decisions involved in building the project or the process followed to make those decisions. You serve as an outside observer to the whole part of the process that as a developer you should be involved in, the decision making, problem solving and architecture.</p>
<p>Following roadmaps and guided resources can be a double-edged sword, with the right mindset they can be infinitely more useful to you than simply learning every technology possible and hoping something sticks. Building your own well-researched roadmap helps you understand why you're learning a certain technology and by understanding the reasons you're covering this material you can hopefully avoid relying on others to tell you in what way to use a tool you already know how to use.</p>
<h2 id="a-jack-of-all-trades-a-master-of-none">A Jack Of All Trades, A Master of None</h2>
<p>To bring it all together, I'll clarify the biggest problem with the majority of learning paths that new developers follow. Whether it's a roadmap; a guided course or simply parsing job descriptions and learning what they list off, a newcomer would believe that there's so many technologies on their radar that they end up being a jack of all trades and a master of none. To become a frontend developer, they would think that even the smallest styling library makes sense to learn compared to the component framework that they would be actually using the vast majority of the time.</p>
<p>By giving equal focus to so many technologies, you can very easily lose sight of what technology is the most important to your role or to the job you're applying for. It's easy to get lost in the details when you don't yet have the insight into the development process to know the value of what you're learning.</p>
<p>The common pitfall here is developers will learn every major component framework on the frontend side or every server framework on the backend side instead of focusing on one and learning the concepts that will easily be transferrable if they move to another.</p>
<p>Earlier I mentioned that learning only the specifics of a framework makes you a framework user and not a developer, which is true, but the critical detail here is that doesn't prevent you from learning those specifics <em>in addition to</em> the concepts that you need to know. Gaining deep knowledge of your tool of choice is always an excellent idea and is necessary to be an effective and productive developer, the mark of a great developer is to know how to eject from this technology into a similar one at will.</p>
<p>To sum up: master the concepts, gain expertise in your technology of choice and focus strongly on gaining general skills in your role rather than learning 1% of every tool available or learning 100% of only one tool. </p>
]]></content:encoded></item><item><title><![CDATA[Accessibility Despite Design]]></title><description><![CDATA[The Role of Accessibility
Accessibility in web design is often an afterthought, at most a designer will care about color contrast, text sizing and other elements meeting the visual part of the Web Content Accessibility Guidelines. While this is somet...]]></description><link>https://blog.raslan.dev/accessibility-despite-design</link><guid isPermaLink="true">https://blog.raslan.dev/accessibility-despite-design</guid><category><![CDATA[Accessibility]]></category><category><![CDATA[Web Accessibility]]></category><category><![CDATA[a11y]]></category><category><![CDATA[Design]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Ali Raslan]]></dc:creator><pubDate>Thu, 19 Aug 2021 00:48:02 GMT</pubDate><content:encoded><![CDATA[<h2 id="the-role-of-accessibility">The Role of Accessibility</h2>
<p>Accessibility in web design is often an afterthought, at most a designer will care about color contrast, text sizing and other elements meeting the visual part of the <a target="_blank" href="https://www.w3.org/WAI/WCAG21/quickref/">Web Content Accessibility Guidelines</a>. While this is something to encourage, it doesn't even scratch the surface of what's needed for the end product to be actually accessible.</p>
<p>For a website to really be accessible, it's up to the developer as well to code with that in mind. From adding alt attributes, <a target="_blank" href="https://www.w3.org/TR/using-aria/">using WAI-ARIA</a> or not using <code>&lt;div&gt;</code> for all content, all these approaches and everything else outlined in the <a target="_blank" href="https://www.w3.org/WAI/WCAG21/quickref/">WCAG</a> are what can really help create more accessible websites.</p>
<p>So why are we talking about designs if it's a developer's problem to implement the accessible parts? Because a developer can only build what was designed correctly in the first place. If a designer is tasked with creating a design for a site, they have the first say in what parts will be accessible.</p>
<h2 id="accessible-vs-aesthetically-pleasing">Accessible vs Aesthetically Pleasing</h2>
<p>When you visit an accessible site, it could look ugly. In fact, it may look old and outdated in many different ways compared to the trends you can find on Dribbble or Behance.</p>
<p>Any accessibility aware designer or developer who inspects such a site and discovers that it's accessible would then sympathize with whomever designed or developed the site. I mean, <em>they had a different goal than making it look good</em>, right?</p>
<p>This is the problem with accessible markup on the web, the belief that an accessible site built for everyone can't have good aesthetics as a goal too, because it's difficult to build a website that looks good and also works for everyone.</p>
<p>In a sense, these simultaneously beautiful and accessible websites would be accessible <em>despite</em> the design, not <em>in conformance</em> to it. Someone explicitly chose to build a custom card component that tries to be accessible or to use pages instead of modals when possible to avoid the common pitfalls of hijacking the page.</p>
<p>These choices weren't enforced by the languages involved, or the technologies powering the web, they weren't enforced by the programs used to design the site or the frameworks used to build it. They were enforced by <em>people</em> who care about others and wanted to design and build something for <em>everyone</em>.</p>
<h2 id="running-away-from-the-problem">Running away from the problem</h2>
<p>The tools we use to build the web may not enforce accessibility best practices, but it's common for companies based in the US afraid of <a target="_blank" href="https://www.lflegal.com/2020/08/quick-fix/">violating the ADA</a> to look for workarounds, shortcuts and ways to sidestep the man hours it takes to build an inclusive product. </p>
<p>They don't want to tell their developers to write accessible markup or to tell their designers to care about designing accessible interfaces because these initiatives could mean hiring more skilled employees or training their existing staff. They just want the equivalent of a normalizer or build tool to do the work for them. </p>
<p>Such tools exist in droves, not linked in this post but easy to find with a web search for "accessibility widget". They all parrot the same promise, pay a small monthly fee and import it and suddenly your whole site is accessible to all and lawsuit-free, does it sound too good to be true?</p>
<p>That's because it is. There's no shortcut to making an accessible website. These websites aren't accessible because the people building them chose to be inclusive, they're accessible (if at all), because they're trying to sidestep legal obligations.</p>
<p>Maybe one day we'll have build tools and external scripts that can truly make our sites accessible. Maybe even further in the future we'll have these tools for <em>free</em> because that's exactly what an open web should cost. Today, some tools exist that achieve the goal some of the time. I'm sure if you're paying a premium for accessibility on your websites, you don't want it to only work <em>sometimes</em>. You wouldn't want it to go away when you stop paying the monthly fee; because under the hood, your website isn't inclusive or accessible. The widget didn't change the problems with your code and designs, it <em>hid</em> them.</p>
<p>So what if you're building or designing a project for yourself or you're a company who wants to build something inclusive but you can't get an accessibility professional to manually audit your designs and test your application?</p>
<h2 id="learning-to-build-differently">Learning to build differently</h2>
<p>There's no end to the references online for writing accessible markup. I don't want to outline some reference or principle as an absolute because, as it turns out, making inclusive interfaces is not easy and thus is open to a lot of subjective views.</p>
<p>A good starting point that I've been following is the <a target="_blank" href="https://www.w3.org/WAI/WCAG21/quickref/">Web Content Accessibility Guidelines Quick Reference</a>, this shows you where to start in terms of making your content accessible. In essence, this is really all you need but a cursory read will reveal that it's not the easiest resource to parse. If you're a designer or a developer, I recommend you start here; I'll also include other more approachable resources below.</p>
<h3 id="for-designers">For designers</h3>
<p>Countless plugins exist for tools like Figma, Sketch and Adobe XD that allow you to check contrast, make sure that font sizes are appropriate and make sure that your content is approachable.</p>
<p>I use Figma, so I can't speak for other tools, but I use the <a target="_blank" href="https://www.figma.com/community/plugin/734693888346260052/Able-%E2%80%93-Friction-free-accessibility">Able</a> and <a target="_blank" href="https://www.figma.com/community/plugin/731310036968334777/A11y---Focus-Orderer">Focus Orderer</a> plugins to both check that my colors are approachable and my designs are keyboard ready.</p>
<h3 id="for-developers">For developers</h3>
<p>the W3C have also created a draft of <a target="_blank" href="https://www.w3.org/TR/using-aria/">how to use ARIA</a> when building websites, this is an essential read if you're a developer who wants to build more inclusive websites.</p>
<p>For those who prefer to approach this with developer documentation rather than reference documents, the Mozilla Developer Network has a wonderful <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Learn/Accessibility">set of guides on Accessibility</a>. These include HTML guidelines, CSS and JavaScript best practices and the basics of using ARIA as linked above. What they also offer is a summary of how to work with mobile devices to be more accessible. So far in this post I've focused mostly on websites since I'm a web designer and developer, but mobile is an equally large if not bigger part of this equation to consider as well.</p>
<p>For a while now, I've been a huge advocate of the principles of inclusive design. Case in point, I think everyone should check out <a target="_blank" href="https://inclusive-components.design/">Inclusive Components</a>. It's a set of docs outlining how to make common component patterns more inclusive and accessible, the author also wrote a book as well as a <a target="_blank" href="https://24ways.org/2016/what-the-heck-is-inclusive-design/">post on inclusive design</a> that I highly recommend you give a look.</p>
<h3 id="bringing-it-all-together">Bringing it all together</h3>
<p>In addition to these resources, I'd like to share some tips from my learning journey that I think can accelerate the process of building inclusive sites. This is by no means a summary or absolute reference, but simply guidelines I picked up along the way that I think can help ease the learning curve a bit.</p>
<h4 id="semantic-html-is-here-to-help">Semantic HTML is here to help</h4>
<p>HTML is made for everyone and just using semantic HTML elements for their purpose already goes a long way. For example: if you need to make a list, there's no reason to make a custom <code>&lt;mylist&gt;</code> component in your framework of choice if <code>&lt;ul&gt;</code> and <code>&lt;ol&gt;</code> exist. More on this is covered in <a target="_blank" href="https://www.w3.org/TR/using-aria/">how to use ARIA</a> and on the <a target="_blank" href="https://inclusive-components.design/">Inclusive Components</a> site.</p>
<h4 id="you-can-still-use-tools">You can still use tools</h4>
<p>Earlier, I mentioned that you shouldn't use a widget that automatically modifies your site and makes it accessible in one go. While this is true, there are tools to <em>augment</em> the development process and help you stay within the Web Content guidelines without having to memorize or to always have the guidelines as shorthand. Examples include Eslint's <a target="_blank" href="https://github.com/jsx-eslint/eslint-plugin-jsx-a11y">JSX-A11y Plugin</a> for React users that helps you write more inclusive markup, alternatives exist for Vue, Angular and probably whatever framework or library you're using as well.</p>
<h4 id="simple-sites-are-not-bad">Simple sites are not bad</h4>
<p>I know that in the age of CSS frameworks being so prevalent and JavaScript frameworks allowing us to create feature-rich and content-rich websites it's easy to scoff at such a remark, but making your website simpler in terms of its markup and navigation can go a long way. A simpler website requires less markup, less JavaScript and probably less CSS as well. It's a lot easier to audit such a site yourself to see if your elements are accessible or not.</p>
<h4 id="develop-with-understanding">Develop with understanding</h4>
<p>When keeping non-sighted users in mind while developing your site, it can be difficult to know the impact of adding an ARIA label or role or the impact of using a link tag to build a card. Installing or enabling a screen reader on your operating system can fix this, use it to audit your own website and see if it's truly easy to navigate using the keyboard and if all the content is there. Bonus points if you do it blindfolded for the extra immersion.</p>
<h4 id="know-your-demographic">Know your demographic</h4>
<p>If you're building a site assuming your content is not going to be useful for a non-sighted user or a user with motor problems or visual/auditory requirements, research your audience and see if your website is indeed only used by people outside those demographics. Chances are if your website is big enough and frequented by enough visitors, this isn't the case.</p>
<h3 id="in-short">In short</h3>
<p>The Internet exists for all of us, not just users who don't have accessibility concerns. It may be difficult to spend the time learning and developing with accessibility in mind, but your pages shouldn't be yet another walled garden that's only accessible to your perceived demographic. The steps you take to make your websites open to everyone may seem thankless; but every time someone who needs those changes visits your site, I guarantee you they'll be grateful that they're enjoying a website that's built with accessibility in mind.</p>
]]></content:encoded></item></channel></rss>