DEV Community

Cover image for Crafting my Portfolio - Meta Tags for SEO
Hardeep Kumar
Hardeep Kumar

Posted on

Crafting my Portfolio - Meta Tags for SEO

This is a Series of Posts where I'm sharing my journey (sort of) while I craft my Portfolio.

Writing this post reminds me of my days with WordPress. I still remember Rank Math was the new kid in the town and I decided to use it because its name sounded cool. Turned out it taught me a few things about SEO. Anyway, The whole game of SEO starts from Meta Tags. Without Meta Tags, there won't be enough information for search engine to act on, causing its visibility to drop. Moreover, say you shared your cool looking website on a social media platform or WhatsApp'd your friend. It's just going to be a link with nothing to say about it.

Now with Nuxt, The good thing is it comes with its inbuilt SEO system. It makes use of vueue/head under the hood to provide an easy-to-access API for manipulating the Meta Tags and other SEO related information in head. More [here].(https://nuxt.com/docs/getting-started/seo-meta)

Title

Now, the first thing I want to do is set a title for my site in Meta Tags. I want it to be like ' | Hardeep Kumar' or just 'Hardeep Kumar' when there is no <page-specified-title>. To do this, I can use titleTemplate. Which could be something like:

useHead({
  titleTemplate: (titleChunk) => {
    return titleChunk ? `${titleChunk} | Hardeep Kumar` : 'Hardeep Kumar';
  },
});
Enter fullscreen mode Exit fullscreen mode

But there is a catch, nuxt.config does not allow functions in it. And it could be bother to mention this in every single page. Also, the later part is supposed to act like a Default or Fallback. Hmm.. Now what? Well, that where plugins system comes in. I can create a Plugin named title and add this logic there, which will be implemented on every page. Also, Nuxt devs mentioned this approach here.

npx nuxi add plugin title
Enter fullscreen mode Exit fullscreen mode
export default defineNuxtPlugin(() => {
  useHead({
    titleTemplate: (titleChunk) => {
      return titleChunk ? `${titleChunk} | Hardeep Kumar` : 'Hardeep Kumar';
    },
  });
});
Enter fullscreen mode Exit fullscreen mode

This will take care of Title.

Find Meta Tags

Title is done, Next up I have to add other relevant Meta Tags to the Pages. But what are those tags going to be? Well One can certainly Google up the answer to that, but it will a bit of trouble to open many websites, write down various tags, then use them etc. To ease the process, I used a site named metaSEO. (I once saw their site https://gprm.itsvg.in in here.)

The process is quite straight forward. I first add my site address.

site address

Then I proceed to add needed Information. It also shows Preview Cards.

preview cards

And finally, press generate to get all the Meta Tags with data prefilled. And these are exactly the tags that I was looking for.

tags

Implement in Nuxt

With the Meta Tags at hand, next I have to implement in my Application. I'll divide few Tags as default, that will be set by default regardless of page. Like copyright... wait... It's just one tag...

Anyway, time to implement them. In various pages, I'll make use of useHead composable to set Meta's data. But yes the syntax of setting tags is a bit different, we can't just set tags in HTML format, It's JS(TS) we're writing here, it's going to be different.

# nuxt.config.ts
....
app: {
  head: {
    meta: [{ name: 'copyright', content: 'Hardeep Kumar' }],
  },
},
....
Enter fullscreen mode Exit fullscreen mode

On Individual Page, Index Here. I also went ahead and add one more tag og:image:alt for embed image alt text.

<script lang="ts" setup>
useHead({
  meta: [
    {
      name: 'description',
      content:
        "Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.",
    },
    {
      name: 'keywords',
      content:
        'Hardeep Kumar, wrench1815, portfolio, Hardeep, website, Web Developer, Nuxt Developer, Vue JS Developer, Django Developer, FastAPI Developer',
    },

    // open graph
    { property: 'og:type', content: 'website' },
    { property: 'og:url', content: 'https://hardeepkumar.in' },
    { property: 'og:title', content: 'Hardeep Kumar' },
    {
      property: 'og:description',
      content:
        "Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.",
    },
    {
      property: 'og:image',
      content:
        'https://res.cloudinary.com/dnzbu6wqv/image/upload/v1669702340/myself/94FKLoemnSP7ikhmOunf--3--2fao5_4x_at5csh.jpg',
    },
    {
      property: 'og:image:alt',
      content: 'Hardeep Kumar AI generated art image',
    },

    // twitter
    { property: 'twitter:card', content: 'summary_large_image' },
    { property: 'twitter:url', content: 'https://hardeepkumar.in' },
    { property: 'twitter:title', content: 'Hardeep Kumar' },
    {
      property: 'twitter:description',
      content:
        "Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.",
    },
    {
      property: 'twitter:image',
      content:
        'https://res.cloudinary.com/dnzbu6wqv/image/upload/v1669702340/myself/94FKLoemnSP7ikhmOunf--3--2fao5_4x_at5csh.jpg',
    },
  ],
});
</script>
Enter fullscreen mode Exit fullscreen mode

Meta tags in Head of Index.

Index Meta tags

No Meta tags for about page except title and copyright. Title being set by plugin and copyright being set via nuxt.config.

no about tags

Now for About Page.

....
useHead({
  title: 'About',

  meta: [
    {
      name: 'description',
      content:
        "Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.",
    },
    {
      name: 'keywords',
      content:
        'Hardeep Kumar, wrench1815, portfolio, Hardeep, website, Web Developer, Nuxt Developer, Vue JS Developer, Django Developer, FastAPI Developer',
    },

    // open graph
    { property: 'og:type', content: 'website' },
    { property: 'og:url', content: 'https://hardeepkumar.in' },
    { property: 'og:title', content: 'Hardeep Kumar' },
    {
      property: 'og:description',
      content:
        "Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.",
    },
    {
      property: 'og:image',
      content:
        'https://res.cloudinary.com/dnzbu6wqv/image/upload/v1669702340/myself/94FKLoemnSP7ikhmOunf--3--2fao5_4x_at5csh.jpg',
    },
    {
      property: 'og:image:alt',
      content: 'Hardeep Kumar AI generated art image',
    },

    // twitter
    { property: 'twitter:card', content: 'summary_large_image' },
    { property: 'twitter:url', content: 'https://hardeepkumar.in' },
    { property: 'twitter:title', content: 'Hardeep Kumar' },
    {
      property: 'twitter:description',
      content:
        "Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.",
    },
    {
      property: 'twitter:image',
      content:
        'https://res.cloudinary.com/dnzbu6wqv/image/upload/v1669702340/myself/94FKLoemnSP7ikhmOunf--3--2fao5_4x_at5csh.jpg',
    },
  ],
});
....
Enter fullscreen mode Exit fullscreen mode

And now About also have its Meta data.

Meta on About


Update

SEO Card Previews

The address being used is Preview deployment.

Note: Twitter has disabled previews in https://cards-dev.twitter.com/validator for the time bieng.

Twitter Card Preview

Twitter Card

Facebook Card Preview

Facebook card

Dev.to Embed preview

I might need to do something about the image... maybe... or maybe not...

Hardeep Kumar

Hi! I'm Hardeep Kumar, a Web Developer. I work with Django. Django REST Framework, FastAPI, Vue JS and Nuxt JS.

hardeepkumar.in

Closing Thoughts

I like the setup so far. It's good for now, but can be improved. I could definitely add a composable to set the meta data by just passing an object with content values. Which I might do, but I still have to run a few tests on how it will behave and how the current setup is behaving on deploy. Or maybe I could have used components instead.
Do tell me for any mistakes or improvements.


Cover Credits: Stephen Phillips - Hostreviews.co.uk

Top comments (0)