1 Develop Front End
This guide outlines the steps to build and integrate a front-end service with the BublCloud platform. It describes how to develop the front-end with service initialization, authentication, secure API interaction, and file handling via the Bubl Controller.
You can use any programming language or framework or front-end framework (React, Vue, Angular etc.) to build your service UI.
To run the Bubl app locally with full authentication and cross-service communication, follow the steps below:
To ensure cookies (e.g. SameSite, Secure, HttpOnly) work correctly across local services, map the local domain to 127.0.0.1.
- Open Notepad as Administrator.
- Open the file:
C:\Windows\System32\drivers\etc\hosts - Add the following line at the end of the file:
127.0.0.1 local-dev.dev-bubl.cloud - Save and close.
β Optional: Refresh DNS with:
ipconfig /flushdns
- Open Terminal:
sudo nano /etc/hosts - Add:
127.0.0.1 local-dev.dev-bubl.cloud - Save (
Ctrl + OβEnter) and exit (Ctrl + X).
β Optional: Flush DNS cache:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
- Open terminal:
sudo nano /etc/hosts - Add:
127.0.0.1 local-dev.dev-bubl.cloud - Save (
Ctrl + OβEnter), then exit (Ctrl + X).
β Optional: Flush DNS cache (depending on distro):
sudo systemd-resolve --flush-caches
Add homepage key to package.json means specifying the base URL where your app will be deployed. This helps tools like Vite, Create React App, or Webpack correctly generate asset paths in the production build.
{
"name": "bubl-frontend",
"version": "1.0.0",
"homepage": "/service/v1/<service-id>"
}
π Replace
<service-id>with your actual service uuid.
This ensures correct asset paths during build and runtime when deployed under nested routes.
If your frontend makes API calls to another service (e.g., api.dev-bubl.cloud) and gets blocked by CORS, you can bypass it during development using either:
Install and enable CORS bypass extensions in your browser:
-
Firefox: CORS Everywhere
β οΈ These extensions are for development use only.
Use this for temporary development sessions where CORS or cookie issues occur.
"C:\Program Files\Google\Chrome\Application\chrome.exe" ^
--disable-web-security ^
--user-data-dir="C:\ChromeDevSession"
open -na "Google Chrome" --args \
--disable-web-security \
--user-data-dir="/tmp/ChromeDevSession"
google-chrome --disable-web-security \
--user-data-dir="/tmp/ChromeDevSession"
π Important: Do not use this browser instance for normal browsing. It has no security restrictions.
To communicate securely with Bubls Backend with your service follow below steps:
Your front-end must read the authentication cookie from the Bubl domain. This cookie contains a auth token required to authenticate your service requests.
Use the token from the Bubl cookie to request an access token (Bearer token) from the Bubl Controller. This token is required for accessing:
- Your serviceβs backend endpoints
- Bubl controller endpoints
Authentication Endpoint
GET "/service/v1/<serviceid>/api/v1/auth
Replace (your-bubl-domain) with your actual Bubl instance domain.
Successful Response
{
"accessToken": "bearer token",
"validUntil": 1750488856
}
- accessToken: The bearer token to be used in subsequent API calls.
- validUntil: Token expiry time in UNIX timestamp format.
Once your front-end is authenticated using the token retrieved from the Bubl cookie, you can securely communicate with backend APIs. Follow the guidelines below for proper integration:
Always use relative paths (not absolute Url’s) when calling backend APIs. This ensures you are calling the same Bubl instances.
/service/v1/<service-uuid>/api/<your-endpoint>
For Example:
/service/v1/92f2e365-fe04-4657-8993-c02510d29e8c/api/data/submit
Add Authorization Header
Include the Bearer token (retrieved using the Bubl cookie) in the request headers:
Sample Request Structure
POST /service/v1/<service-uuid>/api/<your-endpoint> HTTP/1.1
Host: <your-bubl-subdomain>
Authorization: Bearer <auth_token>
Content-Type: application/json
{
"exampleField": "exampleValue"
}
Security Reminder
- Never hard-code tokens in your front-end.
- Always retrieve tokens securely from the cookie and refresh them if needed.
- Backend endpoints should validate the token on every request to ensure proper access control.
Your service must include an index.html file at the root level.
- This file is served by the Bubl Controller to initialize the service.
- It is responsible for loading the correct assets from the CDN.
Your Front-End can make 2 calls directly to the Bubl Controller.
- File Upload
- File Download
So Uplading and Downloading files is pretty simple with Bubl. You just make the call to controller api with a GET or PUT.
To upload a file, include it in the body of the request as form data.
Request Format Example
-
Domain: bubl-domain is the domain of user’s account Bubl
-
Auth Token: auth_token is the token provided to the service on auth call which is passes as a Bearer token.
-
Form Fields
-
file : form parameter is the file which you want to upload
-
key : form parameter is the unique key to map what kind of file this is, for example
_ -
dataType : form parameter is the kind of data. There are two kinds of data in a Bubl.
-
cd - this is common data model, some data is kept common for multiple services to use provided they have access to it.
-
sd - this is service data model, which is only accessible to that particular service.
-
Depending on the dataType, include additional fields:
-
If dataType choosen is cd then, you must also send what is the common data name and level, and you send this in “common Data” and “level” form parameter respectively.
-
If dataType choosen is sd then, you must send what is the service uuid of your service in “serviceUuid” form parameter
-
curl --location 'https://<bubl_domain>/co-nect/v1/unstructureddata' \
--header 'Authorization: Bearer {{auth_token}}' \
--form 'dataType="cd"' \
--form 'commonData="health"' \
--form 'level="500"' \
--form 'file=@"<your unstructured file>"' \
--form 'key="c505fb4d-0cb8-44bc-9356-f0799f3e3327_symptom_1"'
curl --location 'https://<bubl_domain>/co-nect/v1/unstructureddata' \
--header 'Authorization: Bearer <auth_user_token>' \
--form 'dataType="sd"' \
--form 'serviceUuid="<serviceuuid>"' \
--form 'file=@"<your unstructured file>"' \
--form 'key="c505fb4d-0cb8-44bc-9356-f0799f3e3327_symptom_1"'
Response example
{
"imageId":"92f2e365-fe04-4657-8993-c02510d29e9b_30d65735-daeb-4c16-8932-b5197b16c8cf_enc.svg"
}
You would need this implement in back-end a /v1/photos POST endpoint which will be called by controller to store a mapping of this key with all other metadata which is used in getting to files. You should store it to a common data table or a servicedata type whichever you want and have access to.
If you want to do something else with this imageId you can also do it using the response.
The example request body of this /v1/photos POST endpoint is:
{
"key": "c505fb4d-0cb8-44bc-9356-f0799f3e3327_symptom_1",
"value": {
"DataType": "cd",
"ServiceUuid": "92f2e365-fe04-4657-8993-c02510d29e9b",
"Commondata": "health",
"Level": "500",
"UploadKey": "92f2e365-fe04-4657-8993-c02510d29e9b_30d65735-daeb-4c16-8932-b5197b16c8cf_enc.svg"
}
}
{
"key": "c505fb4d-0cb8-44bc-9356-f0799f3e3327_symptom_1",
"value": {
"DataType": "sd",
"ServiceUuid": "92f2e365-fe04-4657-8993-c02510d29e9b",
"Commondata": "",
"Level": "",
"UploadKey": "92f2e365-fe04-4657-8993-c02510d29e9b_30d65735-daeb-4c16-8932-b5197b16c8cf_enc.svg"
}
}
When a file is uploaded, it’s metadata is sent to the service back-end for storing which is now used to request the uploaded file. Here, file key is the key provided by you during file upload, for example consultuuid_questionaire number
Backend Api to call would be ( you can make your own api here instead of /v1/photos/key )
curl --location 'https://<bubl_domain>/service/v1/<serviceuuid>/api/v1/photos/<file key>' \
--header 'Authorization: Bearer <auth_user_token>'
Response example
{
"key": "c505fb4d-0cb8-44bc-9356-f0799f3e3327_symptom_1",
"value": {
"DataType": "cd",
"ServiceUuid": "92f2e365-fe04-4657-8993-c02510d29e9b",
"Commondata": "health",
"Level": "500",
"UploadKey": "92f2e365-fe04-4657-8993-c02510d29e9b_30d65735-daeb-4c16-8932-b5197b16c8cf_enc.svg"
}
}
You will need this response to get the file.
Now, you can use the metadata received above to fetch the uploaded file
Backend Api to call
curl --location 'https://<bubl_domain>/co-nect/v1/unstructureddata?dataType=cd&commonData=health&level=500&fileName=92f2e365-fe04-4657-8993-c02510d29e9b_30d65735-daeb-4c16-8932-b5197b16c8cf_enc.svg' \
--header 'Authorization: Bearer <auth_token>'
Here, the query parameters are the ones you get from file meta data above, fileName is the “UploadKey” from metadata in case of “dataType” = cd, you need to send commonData and level, in case of “dataType” = sd, you need to send serviceUuid
You will receive, your file uploaded against the key you provided above to get meta data.