Converting URL data from Airtable to clickable links in Vue.js

Hey everyone! I’m working on a Vue.js project where I need to display data from Airtable. I’m having trouble making the URL fields show up as proper clickable links instead of just text.

I followed a basic tutorial to connect to the Airtable API and display the data, but I can’t figure out how to format the URL field correctly. Right now the links aren’t working the way I want them to.

Here’s my HTML template:

<div id="content">
    <div class="list-container">
        <div v-for="record in records" class="item">
            <h2>{{ record['fields']['CompanyName'] }}</h2>
            <a :href="record['fields']['Website']['url']" v-if="record['fields']['Website']">
                <span>Description: {{ record['fields']['Description'] }}</span>
            </a>
            <div>
                <em>URL: </em>
                {{ record['fields']['Website'] }}
            </div>                
        </div>
    </div>            
</div>

And here’s my Vue component:

var component = new Vue({
  el: "#content",
  data: {
    records: []
  },
  mounted: function() {
    this.fetchData();
  },
  methods: {
    fetchData: function() {
      var vm = this;
      var base_id = "---";
      var api_token = "---";
      this.records = [];
      axios
        .get(
          "https://api.airtable.com/v0/" +
            base_id +
            "/Companies?view=Main%20view",
          {
            headers: { Authorization: "Bearer " + api_token }
          }
        )
        .then(function(result) {
          vm.records = result.data.records;
        })
        .catch(function(err) {
          console.log(err);
        });
    }
  }
});

What’s the right way to handle URL fields from Airtable in Vue? Any help would be great!

Check if your Airtable field is set to URL type. I had the same issue - my field was single line text instead of URL in the base settings. URL fields act differently from text fields when you pull them through the API. Could save you some debugging time.

Had this exact problem building a directory app with Airtable and Vue. Airtable’s URL fields are inconsistent - sometimes they return strings, sometimes objects with a ‘url’ property. I fixed it by creating a helper function that checks the field type and returns the right URL format. Also crucial: handle empty or undefined URLs. My app crashed hard on records with missing website data. Watch out for URLs without http:// prefixes too. I made a small utility function that validates and formats URLs before they hit the href attribute. Saved me tons of headaches.

Your template’s wrapping the description in the anchor tag instead of making the URL clickable. Here’s how to fix it:

<div v-for="record in records" class="item">
    <h2>{{ record['fields']['CompanyName'] }}</h2>
    <p>Description: {{ record['fields']['Description'] }}</p>
    <div v-if="record['fields']['Website']">
        <em>URL: </em>
        <a :href="getUrl(record['fields']['Website'])" target="_blank">
            {{ getUrl(record['fields']['Website']) }}
        </a>
    </div>
</div>

Add this method to handle URL extraction:

getUrl: function(websiteField) {
    return typeof websiteField === 'string' ? websiteField : websiteField.url;
}

This works with both string URLs and Airtable’s object format. The target=“_blank” opens links in new tabs like users expect.

I’ve hit this Airtable URL mess countless times. The problem is Airtable sends URLs in different formats depending on how users enter them.

Your template structure is mixing up what should be clickable. Here’s what works:

<div v-for="record in records" class="item">
    <h2>{{ record['fields']['CompanyName'] }}</h2>
    <p>Description: {{ record['fields']['Description'] }}</p>
    <div v-if="record['fields']['Website']">
        <em>URL: </em>
        <a :href="normalizeUrl(record['fields']['Website'])" 
           target="_blank" 
           rel="noopener">
            Visit Website
        </a>
    </div>
</div>

Add this method to your Vue component:

normalizeUrl: function(urlField) {
    if (!urlField) return '#';
    
    let url = typeof urlField === 'string' ? urlField : urlField.url;
    
    // Add protocol if missing
    if (url && !url.match(/^https?:\/\//)) {
        url = 'https://' + url;
    }
    
    return url || '#';
}

This fixes the protocol issue that trips everyone up. Users enter “example.com” instead of “https://example.com” and browsers won’t navigate without the protocol.

This video covers exactly what you need for URL links in Vue:

The rel=“noopener” is for security with target=“_blank”. Learned that during a painful security audit.

Had the same frustrating issue until I figured out what’s wrong. Your anchor tag is wrapping the description text instead of making a proper clickable link. You need to separate the URL display from the actual link.

Here’s how to fix it:

<div v-for="record in records" class="item">
    <h2>{{ record['fields']['CompanyName'] }}</h2>
    <p>Description: {{ record['fields']['Description'] }}</p>
    <div v-if="record['fields']['Website']">
        <em>URL: </em>
        <a :href="formatWebsiteUrl(record['fields']['Website'])" target="_blank">
            {{ record['fields']['Website']['url'] || record['fields']['Website'] }}
        </a>
    </div>
</div>

Add this method for URL formatting:

formatWebsiteUrl: function(website) {
    if (typeof website === 'object' && website.url) {
        return website.url;
    }
    return website;
}

This separates your description from the link and handles both string and object URL formats from Airtable. The trick is making sure your anchor tag only wraps what should be clickable.