I'm trying to embed an Apache 1.5 dashboard in a Wordpress site. So far I've succeeded in doing the following:
Upgrade to Apache Superset 1.5 and enable the embedded dashboard functionality
Configure dashboard to be embedded
Implemented backend code to obtain JWT token
What I'm struggling with now is to implement the "#superset-ui/embedded-sdk" functionality in my Wordpress site (using TwentyTwentyOne standard template). I'm trying to follow the instructions listed here: https://fossies.org/dox/apache-superset-1.5.0-source/md_superset_embedded_sdk_README.html
The CDN approach looks the easiest, but I'm getting the error ReferenceError: Buffer is not defined. And if I add the following code:
<script src="https://unpkg.com/buffer"></script>
Then I get the error ReferenceError: require is not defined. I'm not sure how I can resolve this error. Is the CDN approach a dead end, or is there a way I can make this work?
With the "Using npm" approach I'm struggling even more. I'm able to install the npm packages on bitnami linux, but then I don't know how to make use of them in the site. I wasn't able to make it work to add '#superset-ui/embedded-sdk' using wp_enqueue_script(). Also I tried the following code in wordpress:
<script type="module">
import {embedDashboard} from 'http://[MY_IP_ADDRESS]/wp-content/themes/twentytwentyone/node_modules/#superset-ui/embedded-sdk/lib/index.js';
</script>
However then I get the following error:
Uncaught SyntaxError: The requested module 'http://[MY_IP_ADDRESS]/wp-content/themes/twentytwentyone/node_modules/#superset-ui/embedded-sdk/lib/index.js' does not provide an export named 'embedDashboard'
I don't quite understand this error as embedDashboard does appear to be defined in the js file. I also tried using the embedded-sdk/bundle/index.js file with the same result.
I've spent many hours on this and I'm not sure what approach I should take. Can anyone point me in the right direction? Or even better: have a solution to a similar problem with sample code I can look at? If I need to provide more details on what I've tried or what errors I'm seeing let me know.
This is how I did it.
I wrote my backend in Flask.
My Superset Version is 2.0
backend.py
from flask import Flask, render_template, jsonify
import requests
import json
import os
app = Flask(__name__)
#app.route('/')
def hello():
return render_template('index.html')
#app.route("/guest-token", methods=["GET"])
def guest_token():
url = "http://<IP>:<PORT>/api/v1/security/login"
payload = json.dumps({ "password": "<>", "provider": "db", "refresh": "true", "username": "<>" })
headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' }
responsel = requests.request("POST", url, headers=headers, data=payload)
print(responsel.text)
superset_access_token = json.loads(responsel.text)['access_token']
payload = json.dumps ({
"user": {
"username": "kashew",
"first name":"Kashish",
"lastname":"Bakshi"
},
"resources": [{
"type": "dashboard",
"id": "8f96cc84-7e9e-4f5c-ba92-3a1f0825fe3d"
}],
"rls": []
})
bearer_token = "Bearer " + superset_access_token
print(bearer_token)
response2 = requests.post(
"http://<IP>:<PORT>/api/v1/security/guest_token",
data = payload,
headers = { "Authorization": bearer_token, 'Accept': 'application/json', 'Content-Type': 'application/json' })
print(response2.json())
return jsonify(response2.json()['token'])
if __name__ == "__main__":
app.run(debug=True)
Explanation:
The Major part of understanding is the Guest_Token Function.
Here two POST Requests are at play.
The first Request gets the access token from Superset.
The Second request uses the Access Token we got as Bearer and is a POST Call to get the Guest_Token from Superset.
Payload for Guest_Token:
{
"user": {
"username": "kashew",
"first name":"Kashish",
"lastname":"Bakshi"
},
"resources": [{
"type": "dashboard",
"id": "8f96cc84-7e9e-4f5c-ba92-3a1f0825fe3d"
}],
"rls": []
}
Explanation:
The Payload is a JSON with 3 Key-Value Pair.
user (Here, I created a Dummy User{ This can be replaced with your App Auth Logic})
resources (Refer this)
rls (I kept it empty but more can be found here)
I ran my backend on Localhost:5000.
For Frontend, I created a directory "templates" and put my index.html file inside it.
index.html
<html>
<head>
<script src="https://unpkg.com/#superset-ui/embedded-sdk"></script>
<style>
iframe {
width: 100%;
height: 50%;
border: none;
pretext {
margin-right: 10%;
margin-left: 10%;
font-family: Tahoma;
</style>
</head>
<body>
<div class="pretext">
<h2> Covid Statistics </h2>
<p> Dive into Covid data
<p id="dashboard-container"></p>
<script>
async function fetchGuestTokenFromBackend() {
let response = await fetch('http://127.0.0.1:5000/guest-token');
let data = await response.json()
return data
}
const myDashboard = supersetEmbeddedSdk.embedDashboard({
id: "8f96cc84-7e9e-4f5c-ba92-3a1f0825fe3d",
supersetDomain: "http://<IP>:<PORT>",
mountPoint: document.getElementById("dashboard-container"),
fetchGuestToken: () => fetchGuestTokenFromBackend(),
dashboardUiConfig: {
hideTitle: true,
hideChartControls: true
},
});
</script>
</div>
</body>
</html>
Explanation:
It calls my guest-token method which returns a Guest-Token to my frontend. The Frontend then makes a request to Superset Embed Dashboard URL with the guest-token which in turn embeds and renders the chart in an Iframe on my website.
Hello, I hope this example of using 'superset embedded-sdk' will help you:
<!DOCTYPE html>
<head>
...
<script src="https://unpkg.com/#superset-ui/embedded-sdk"></script>
</head>
<body>
<p id="dashboard" width="700" height="700"></p>
<script>
async function getToken() {
const res = await fetch('http://localhost:3000/token');
const data = await res.json()
console.log(data['value']);
return data['value'];
}
supersetEmbeddedSdk.embedDashboard({
id: "7b5ee110-435b-4ad1-a257-97ea340bf82d",
supersetDomain: "http://localhost:8088",
mountPoint: document.getElementById("dashboard"),
fetchGuestToken: () => getToken(),
dashboardUiConfig: {
hideTitle: true,
filters: {
expanded: true
}
}
});
</script>
</body>
</html>
Related
I'm trying to make an API call from my Vue3 app. The prepared API has an endpoint like http://localhost:8888/api/dtconfigsearch, where one needs to pass a json payload like { "Modelname": "MyFancyModel"} to get the full dataset with the given modelname. Pure get functions without a payload / a body do work from my Vue3 project to the golang backend, but I'm having problems with passing a payload to the backend.
Test with curl -> ok
$ curl -XGET localhost:8888/api/dtconfigsearch -d '{"Modelname" : "MyFancyModel" }'
{"ID":4,"Modelname":"MyFancyModel","ModelId":"96ee6e80-8d4a-b59a-3524-ced3187ce7144000","OutputTopic":"json/fancyoutput"}
$
This is the expected output.
Test with javascript ok
Source file index.js:
const axios = require('axios');
function makeGetRequest() {
axios.get(
'http://localhost:8888/api/dtconfigsearch',
{
data: { Modelname : "MyFancyModel" },
headers: {
'Content-type' : 'application/json'
}
}
)
.then(resp => {
console.log(resp.data)
})
.catch(err => {
console.log(err)
})
}
makeGetRequest()
Output
$ node index.js
{
ID: 4,
Modelname: 'MyFancyModel',
ModelId: '96ee6e80-8d4a-b59a-3524-ced3187ce7144000',
OutputTopic: 'json/fancyoutput'
}
$
Here, I also get the desired output.
Test within Vue fails :-(
Source in the Vue one file component:
onSelection(event) {
let searchPattern = { Modelname : event.target.value }
console.log(event.target.value)
console.log("searchPattern = " + searchPattern)
axios.get("http://localhost:8888/api/dtconfigsearch",
{
data : { Modelname : "Windshield"},
headers: {
'Content-type' : 'application/json',
'Access-Control-Allow-Origin': '*'
}
})
.then(response => {
console.log(response.data)
})
.catch(err => {
console.log(err)
alert("Model with name " + event.target.value + " not found in database")
})
},
Output in browser:
In the image you can see in the terminal log on the right side that the backend is not receiving the body of the API call. However, in the browser information of the call there is content in the config.data part of the object tree, which is the payload / the body. The only thing that bothers me that it is not a json object, but stringified json, although it was entered as json object. According to the documentation, the parameter name (data) in the call should be correct to hold the body content of the api call.
I've tried different header information, looked if it could be a CORS issue, what it isn't to my opinion, exchanged key data with body, used axios instead of axios.get and adapted parameter, all without success. The version of the axios library is 0.27, identical for Vue and vanilla javascript. After checking successfully in javascript, I was sure that it would work the same way in Vue, but it didn't.
Now I'm lost and have no further ideas how to make it work. Maybe someone of you had similar issues and could give me a hint? I'd be very grateful for some tipps!!
I'm a junior developer that's fairly new to using Facebook for Developers. I'm hitting a wall with the ReactJs application I'm building and could use your help!
My boss has requested a Grid representation of the Page Plugin, not the actual Plugin itself. For this project, he's requested I make and use a test 'Page' I've found that DevExtreme's Data Grid seems to be the best option in terms of the desired visual, and I'm trying to call my Facebook Page using the Graph API documentation. I know it's hitting at least the area I want it to with my console.log because it's returning the error message.
Here are the errors my browser is returning:
Access to fetch at 'https://www.facebook.com/Feeds-Tester-170107151801959/' from origin 'https://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
GET https://www.facebook.com/Feeds-Tester-170107151801959/ net::ERR_FAILED
The link you'll see referenced in my URL variable has been triple checked to be the correct link. Since I'm using NodeJS, I tried installing the CORS npm package but I'm not 100% sure where to put it to use it, I'm wondering if that's the cause of the issue?
Here's my full code snippet (I'm using VS Code, if that helps):
/*global FB*/
import React from 'react';
import { DataGrid, Editing, Scrolling, Lookup, Summary, TotalItem } from 'devextreme-react/data-grid';
import { Button } from 'devextreme-react/button';
import { SelectBox } from 'devextreme-react/select-box';
import CustomStore from 'devextreme/data/custom_store';
import { formatDate } from 'devextreme/localization';
import 'whatwg-fetch';
const URL = 'https://www.facebook.com/Feeds-Tester-170107151801959/';
const REFRESH_MODES = ['full', 'reshape', 'repaint'];
class Grid extends React.Component {
constructor(props) {
super(props);
this.state = {
fbData: null,
ordersData: new CustomStore({
key: 'OrderID',
load: () => this.sendRequest(`${URL}`, 'GET'),
}),
requests: [],
refreshMode: 'reshape'
};
this.clearRequests = this.clearRequests.bind(this);
this.handleRefreshModeChange = this.handleRefreshModeChange.bind(this);
var body = 'Reading JS SDK documentation';
FB.api('/me/feed', 'post', { message: body }, function(response) {
if (!response || response.error) {
console.log('Error occured');
} else {
console.log('Post ID: ' + response.id);
}
})
}
sendRequest(url, method, data) {
method = method || 'GET';
data = data || {};
this.logRequest(method, url, data);
if(method === 'GET') {
return fetch(url, {
method: method,
credentials: 'include',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Access-Control-Allow-Origin': '*'
}
}).then(result => result.json().then(json => {
if(result.ok) return json.data;
throw json.Message;
}));
}
const params = Object.keys(data).map((key) => {
return `${encodeURIComponent(key) }=${ encodeURIComponent(data[key])}`;
}).join('&');
return fetch(url, {
method: method,
body: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
credentials: 'include'
}).then(result => {
if(result.ok) {
return result.text().then(text => text && JSON.parse(text));
} else {
return result.json().then(json => {
throw json.Message;
});
}
});
}
logRequest(method, url, data) {
const args = Object.keys(data || {}).map(function(key) {
return `${key }=${ data[key]}`;
}).join(' ');
const time = formatDate(new Date(), 'HH:mm:ss');
const request = [time, method, url.slice(URL.length), args].join(' ');
this.setState((state) => {
return { requests: [request].concat(state.requests) };
});
}
clearRequests() {
this.setState({ requests: [] });
}
handleRefreshModeChange(e) {
this.setState({ refreshMode: e.value });
}
render() {
const { refreshMode, ordersData } = this.state;
return (
<React.Fragment>
<DataGrid
id="grid"
showBorders={true}
dataSource={ordersData}
repaintChangesOnly={true}
>
<Editing
refreshMode={refreshMode}
mode="cell"
allowAdding={true}
allowDeleting={true}
allowUpdating={true}
/>
<Scrolling
mode="virtual"
/>
<Lookup dataSource={ordersData} valueExpr="Value" displayExpr="Text" />
<Summary>
{/* <TotalItem column="CustomerID" summaryType="count" />
<TotalItem column="Freight" summaryType="sum" valueFormat="#0.00" /> */}
</Summary>
</DataGrid>
<div className="options">
<div className="caption">Options</div>
<div className="option">
<span>Refresh Mode: </span>
<SelectBox
value={refreshMode}
items={REFRESH_MODES}
onValueChanged={this.handleRefreshModeChange}
/>
</div>
<div id="requests">
<div>
<div className="caption">Network Requests</div>
<Button id="clear" text="Clear" onClick={this.clearRequests} />
</div>
<ul>
{this.state.requests.map((request, index) => <li key={index}>{request}</li>)}
</ul>
</div>
</div>
</React.Fragment>
);
}
}
export default Grid;
This is the link to the docs for the module I'm trying to reference
I'm trying to not bite off more than I can chew and just start with retrieving the data before I even think about manipulating it or sending any in return. Any insight or guidance you can provide would be greatly appreciated. Thank you!! :)
Do not use fetch with the Facebook URL, it won't let it happen on the browser, instead, use the Facebook API for everything you need to do with it
For example, instead of fetching the page, use the api with the page
FB.api('/Feeds-Tester-170107151801959', function(response) {
// ...
});
If you need to fetch the page, then you have to do it outside the browser environment or use a proxy like cors anywhere, but you can avoid that by using the Facebook API
I was also getting these error. I found that the pageId, I was using was wrong🤦♀️. These errors come only when your pageId is wrong or the domain is not whitelisted properly(I even tried with a ngrok url and it worked😵).
So the steps which I followed were:
In buisness.facebook.com go to inbox from sidebar and select chat plugin. [https://i.stack.imgur.com/rDk5d.png]
Click on setup to add your domain. [https://i.stack.imgur.com/exOi2.png]
Pick a setup method(standard for react/nextjs) and setup chat plugin(add language, domain, copy code and paste it). [https://i.stack.imgur.com/hDArZ.png]
You can add multiple domains. [https://i.stack.imgur.com/zGdgx.png]
You will get pageId already embedded. [https://i.stack.imgur.com/iRT13.png]
Use this code and paste it in _document.js file in nextjs. and after deploying it will work perfectly. For any confusion please let me know. Thanks, Happy Coding ☺
I really do NOT understand how I'm supposed to make this work:
var requestURL = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw';
console.log(requestURL);
$.getJSON( requestURL, function( data ) {
// data
console.log(data);
});
and my HTML file:
<body>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="main.js" charset="utf-8"></script>
</body>
I always get the No 'Access-Control-Allow-Origin' header is present on the requested resource. message... even though if I go to https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw in my browser I get the proper JSON returned.
I am lead to believe that CORS can help me here. I don't understand CORS. Please, can anyone help me in plain simple terms? What should I change to make this work??
Thanks
You are trying to use the Google Places API Web Service on client side whereas it is designed for server side applications. That's probably why appropriate CORS response headers are not set by the server.
As explained in the Notes at the beginning of the Place Details documentation, you should use the Places Library in the Google Maps JavaScript API:
If you're building a client-side application, take a look at the Google Places API for Android, the Google Places API for iOS, and the Places Library in the Google Maps JavaScript API.
Note: you will need to enable the Google Maps JavaScript API in your Google Developer Console first.
Here is a way you can proceed to get place details (based on the example from the documentation):
<head>
<script type="text/javascript">
function logPlaceDetails() {
var service = new google.maps.places.PlacesService(document.getElementById('map'));
service.getDetails({
placeId: 'ChIJN1t_tDeuEmsRUsoyG83frY4'
}, function (place, status) {
console.log('Place details:', place);
});
}
</script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw&libraries=places&callback=logPlaceDetails"></script>
</head>
<body>
<div id="map"></div>
</body>
#rd3n already answered about why to use Google Maps' SDK, but if you really need to use the API instead of SDK on a web app (reuse code, for exemple), you can bypass CORS using proxy parameter from Webpack's DevServer.
const GMAPS_PLACES_AUTOCOMPLETE_URL = (
process.env.NODE_ENV === 'production'
? 'https://maps.googleapis.com/maps/api/place/autocomplete/json'
: 'place-api' // on development, we'll use the Webpack's dev server to redirect the request
const urlParams = new URLSearchParams([
...
])
const response = await fetch(
`${GMAPS_PLACES_AUTOCOMPLETE_URL}?${urlParams}`,
{ method: 'GET' }
)
And on your webpack.config.js...
module.exports = {
devServer: {
proxy: {
'/place-api': {
target: 'https://maps.googleapis.com/maps/api/place/autocomplete/json',
changeOrigin: true,
pathRewrite: { '^/place-api': '' }
}
}
}
}
I know this is an old question, and this might not be a direct answer to this question, but just in case someone could use this trick, I always like to go around this issue using PHP to create my own API, then fetch the newly created API using JavaScript:
1# Create an api.php file:
<?php
$google_URL = 'https://maps.googleapis.com/maps/api/place/details/json';
$api = 'YOUR_GOOGLE_API';
$place = 'PLACE_ID';
$field = [
'user_ratings_total',
'rating'
];
$fields = join(",", $field);
$result_url = $google_URL.'?placeid='.$place.'&fields='.$fields.'&key='.$api;
$result_content = file_get_contents($result_url);
$json_data = json_decode($result_content, true);
if ( isset($json_data) && $json_data['status'] === 'OK' ) {
echo json_encode($json_data['result']);
}else {
echo json_encode($json_data['error_message']);
}
header("content-type: application/json");
2# Create a script.js file:
const url = './api.php';
fetch(url)
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.log(error))
Using the same url you provided, this is for pure front-end (React), but a less secure solution:
var requestURL = 'https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw';
Cut out the following from url: 'https://maps.googleapis.com/maps/api/place' and create a proxy line in your package.json:
"proxy": "https://maps.googleapis.com/maps/api/place"
Then following google documentations you'll be left with the following code (wherever you're fetching the api):
var axios = require('axios');
var config = {
method: 'get',
url: '/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=AIzaSyAW4CQp3KxwYkrHFZERfcGSl--rFce4tNw', //the rest of your url
secure: false //important
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
I am trying to create an online meeting and recover its URL like explained here in the docs, but when the request is run I get this error:
{
"statusCode": 400,
"code": "AuthenticationError",
"message": "Error authenticating with resource",
"requestId": "652ea3be-6a97-47e8-bfc6-3d7d1d51d425",
"date": "2020-09-01T12:53:41.000Z",
"body": "{
"code":"AuthenticationError",
"message":"Error authenticating with resource",
"innerError":{
"date":"2020-09-01T13:53:41",
"request-id":"652ea3be-6a97-47e8-bfc6-3d7d1d51d425"
}
}"
}
I tried also the get started projet for JS and it's working fine so I can't spot the problem.
here is what I used:
const msalConfig = {
auth: {
clientId: 'my_app_id',
redirectUri: 'http://localhost:8080'
},
cache: {
cacheLocation: "sessionStorage",
storeAuthStateInCookie: false,
forceRefresh: false
}
};
const loginRequest = { scopes: [
'openid',
'profile',
'user.read',
'calendars.read',
'User.Read.All',
'User.Export.All'
]
}
const options = new MicrosoftGraph.MSALAuthenticationProviderOptions([
'user.read',
'calendars.read',
'OnlineMeetings.ReadWrite'
]);
const onlineMeeting = {
startDateTime:"2020-09-01T16:00:34.2444915-07:00",
endDateTime:"2020-09-01T16:30:34.2464912-07:00",
subject:"test meeting"
};
const authProvider = new MicrosoftGraph.ImplicitMSALAuthenticationProvider(msalClient, options);
// Initialize the Graph client
const graphClient = MicrosoftGraph.Client.initWithMiddleware({authProvider});
// then I call this inside an async function
let events = await graphClient.api('/users/my_UserPrincipalName/onlineMeetings').post(onlineMeeting);
//let events = await graphClient.api('/me/onlineMeetings').post(onlineMeeting);
// I tried with both calls and none of them worked
and here are the permissions on azure active directory:
So any ideas on how to solve this ?
thanks
You didn't provide a correct access token.
Since Create onlineMeeting only supports Delegated (work or school account) permission type, you need to get the access token with Auth code flow or Implicit flow.
The started project for JS is using Implicit flow. So you can use Implicit flow to get the access token.
Here is the example in Postman:
The Auth URL above is https://login.microsoftonline.com/{your tenant}/oauth2/v2.0/authorize.
I figured out how to make it work in my code:
let's call my user, which I used all this time, user "A", all I did is that I simply created another user "B" in Azure Active Directory and then logging in with this new user "B" in the login screen instead of the admin user "A" that I used before..... and now it's working.
But this does not explain the issue, so if anyone can explain the difference or why it didn't work with the first account, that would be very helpful.
I am a bit new to VueJS and I am using Laravel as API only and VueJS as a separate project.
In my App.vue, I have following setup:
http://api.com is my virtual host!
<script>
import axios from 'axios';
export default {
data () {
return {
}
},
created() {
const postData = {
grant_type: "password",
client_id: 2,
client_secret: 'MvEyvm3MMr0VJ5BlrJyzoKzsjmrVpAXp9FxJHsau',
username: 'mail#gmail.com',
password: '**********',
scope: ''
}
axios.post('http://api.com/oauth/token', postData)
.then(response => {
const header = {
'Accept': 'application/json',
'Authorization': 'Bearer ' + response.data.access_token,
};
axios.get('http://api.com/api/user', { headers: header })
.then(response => {
console.log(response.data)
})
})
}
}
</script>
But this file is totally visible to front-end which is not good due to security reasons.
What I did, I made a new route in Laravel as Route::post('get_client_creds', MyController#index); and then made a request from axios as:
axios.post('http://api.com/get_client_creds')
.then(response => {
this.client_secret = response.client_secret;
});
And but then I thought anyone can also access the route using Postman or may be through console using axois, so can someone give me some suggestions about where to store these secrets???
Thanks in Advance!
There are two different ways to specify config settings for vue
#1 Vue.js non-cli projects, you can use src/config.js
Create a new file src/config.js and add as following
export const API_CLIENT_ID = '123654';
To use this, try import like:
import { API_CLIENT_ID } from '../config'
// in your code
console.log(API_CLIENT_ID);
#2 For Vue CLi projects follow these steps.
You must use the .env files hold the configuration variables.
It could be structured like
.env # loaded in all cases
.env.local # loaded in all cases, ignored by git
.env.[mode] # only loaded in specified mode
.env.[mode].local # only loaded in specified mode, ignored by git
Here is how you can specify the variable.
FOO=bar
API_CLIENT_ID=123456
And you can use this as:
console.log(process.env.API_CLIENT_ID)
Please follow the documentation for more details.
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables