Skip to content

Commit 7647f38

Browse files
committed
feat: add config module to load API URL from .env file across all platforms
1 parent 850597e commit 7647f38

File tree

12 files changed

+300
-38
lines changed

12 files changed

+300
-38
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Server configuration
22
PORT=3000
33

4+
# API configuration
5+
API_BASE_URL=https://profullstack.com/pdf
6+
47
# Puppeteer configuration
58
# If not set, the application will try to auto-detect the Chrome path based on the environment
69
# Production path example:

README-native-apps.md

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,39 +46,66 @@ The desktop app uses Electron to load the PWA from the production website. It pr
4646

4747
See the [Desktop README](./desktop/README.md) for detailed instructions on building and running the desktop app.
4848

49-
## Customization
49+
## Configuration
5050

51-
All apps can be easily customized to point to different environments (development, staging, production) by modifying the URL in the respective WebView implementation.
51+
All apps are configured to load the PWA URL from the `API_BASE_URL` variable in the project's root `.env` file. This allows you to easily switch between different environments (development, staging, production) by modifying a single configuration file.
5252

53-
### iOS URL Configuration
53+
### .env Configuration
5454

55-
In `ios/PDFConverter/PDFConverter/ViewController.swift`:
55+
In the project root's `.env` file:
56+
57+
```
58+
API_BASE_URL=https://profullstack.com/pdf
59+
```
60+
61+
### How Each App Reads the Configuration
62+
63+
#### iOS App
64+
65+
The iOS app uses a `Config.swift` file that reads from the `.env` file in the project root:
5666

5767
```swift
58-
private func loadWebsite() {
59-
if let url = URL(string: "https://profullstack.com/pdf") {
60-
let request = URLRequest(url: url)
61-
webView.load(request)
62-
}
68+
// In Config.swift
69+
static let apiBaseURL: String = {
70+
// Try to read from .env file in the project root
71+
// Falls back to default URL if not found
72+
}()
73+
74+
// In ViewController.swift
75+
if let url = URL(string: Config.apiBaseURL) {
76+
let request = URLRequest(url: url)
77+
webView.load(request)
6378
}
6479
```
6580

66-
### Android URL Configuration
81+
#### Android App
6782

68-
In `android/PDFConverter/app/src/main/java/com/profullstack/pdfconverter/MainActivity.kt`:
83+
The Android app uses a `Config.kt` file that reads from the `.env` file in the project root:
6984

7085
```kotlin
71-
// URL of the PWA
72-
private val pwaUrl = "https://profullstack.com/pdf"
86+
// In Config.kt
87+
fun getApiBaseUrl(context: Context): String {
88+
// Try to read from .env file in the project root
89+
// Falls back to default URL if not found
90+
}
91+
92+
// In MainActivity.kt
93+
pwaUrl = Config.getApiBaseUrl(this)
7394
```
7495

75-
### Desktop URL Configuration
96+
#### Desktop App
7697

77-
In `desktop/src/main.js`:
98+
The desktop app uses a `config.js` file that reads from the `.env` file in the project root:
7899

79100
```javascript
80-
// URL of the PWA
81-
const pwaUrl = 'https://profullstack.com/pdf';
101+
// In config.js
102+
function getApiBaseUrl() {
103+
// Try to read from .env file in the project root
104+
// Falls back to default URL if not found
105+
}
106+
107+
// In main.js
108+
const pwaUrl = getApiBaseUrl();
82109
```
83110

84111
## Benefits of Native WebView Apps
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.profullstack.pdfconverter
2+
3+
import android.content.Context
4+
import java.io.File
5+
import java.io.FileInputStream
6+
import java.util.Properties
7+
8+
object Config {
9+
// Default fallback URL
10+
private const val DEFAULT_API_BASE_URL = "https://profullstack.com/pdf"
11+
12+
// Get API base URL from .env file
13+
fun getApiBaseUrl(context: Context): String {
14+
try {
15+
// Try to find the .env file in the project root
16+
// First, try to find it relative to the app's files directory
17+
val appDir = context.filesDir.parentFile?.parentFile?.parentFile?.parentFile?.parentFile
18+
val envFile = File(appDir, ".env")
19+
20+
if (envFile.exists()) {
21+
return parseEnvFile(envFile)
22+
}
23+
24+
// If not found, try to find it in external storage (for development)
25+
val externalDir = context.getExternalFilesDir(null)?.parentFile?.parentFile?.parentFile?.parentFile
26+
val externalEnvFile = File(externalDir, ".env")
27+
28+
if (externalEnvFile.exists()) {
29+
return parseEnvFile(externalEnvFile)
30+
}
31+
} catch (e: Exception) {
32+
e.printStackTrace()
33+
}
34+
35+
// Return default URL if .env file not found or error occurs
36+
return DEFAULT_API_BASE_URL
37+
}
38+
39+
private fun parseEnvFile(envFile: File): String {
40+
val properties = Properties()
41+
FileInputStream(envFile).use { input ->
42+
properties.load(input)
43+
}
44+
45+
// Get API_BASE_URL from properties
46+
val apiBaseUrl = properties.getProperty("API_BASE_URL")
47+
48+
// Return the URL if found, otherwise return default
49+
return apiBaseUrl ?: DEFAULT_API_BASE_URL
50+
}
51+
}

android/PDFConverter/app/src/main/java/com/profullstack/pdfconverter/MainActivity.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
1313
class MainActivity : AppCompatActivity() {
1414
private lateinit var webView: WebView
1515
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
16+
// URL of the PWA - will be loaded from .env file
17+
private lateinit var pwaUrl: String
1618

17-
// URL of the PWA
18-
private val pwaUrl = "https://profullstack.com/pdf"
1919

2020
@SuppressLint("SetJavaScriptEnabled")
2121
override fun onCreate(savedInstanceState: Bundle?) {
2222
super.onCreate(savedInstanceState)
2323
setContentView(R.layout.activity_main)
2424

25+
// Get API base URL from .env file
26+
pwaUrl = Config.getApiBaseUrl(this)
27+
2528
// Initialize WebView
2629
webView = findViewById(R.id.webView)
2730
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)

android/README.md

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ A simple Android app that uses WebView to load the PDF Converter PWA from the pr
44

55
## Features
66

7-
- Loads the PWA from https://profullstack.com/pdf
7+
- Loads the PWA from the URL specified in the project's root .env file
88
- Supports all PWA features through WebView
99
- Pull-to-refresh functionality
1010
- Handles back navigation within the WebView
@@ -27,17 +27,51 @@ A simple Android app that uses WebView to load the PDF Converter PWA from the pr
2727
## Project Structure
2828

2929
- `MainActivity.kt`: Main activity with WebView implementation
30+
- `Config.kt`: Configuration class that reads from the .env file
3031
- `activity_main.xml`: Main layout with WebView and SwipeRefreshLayout
3132
- `AndroidManifest.xml`: App configuration and permissions
3233
- `build.gradle`: Project and app-level build configurations
3334

34-
## Customization
35+
## Configuration
3536

36-
To change the URL of the PWA, modify the `pwaUrl` variable in `MainActivity.kt`:
37+
The app reads the PWA URL from the `API_BASE_URL` variable in the project's root `.env` file. This allows you to easily switch between different environments (development, staging, production) by modifying a single configuration file.
38+
39+
### How It Works
40+
41+
The `Config.kt` file reads the API_BASE_URL from the .env file:
42+
43+
```kotlin
44+
// In Config.kt
45+
object Config {
46+
// Default fallback URL
47+
private const val DEFAULT_API_BASE_URL = "https://profullstack.com/pdf"
48+
49+
// Get API base URL from .env file
50+
fun getApiBaseUrl(context: Context): String {
51+
// Try to find and parse the .env file
52+
// ...parsing logic...
53+
54+
// Return default URL if .env file not found or error occurs
55+
return DEFAULT_API_BASE_URL
56+
}
57+
}
58+
```
59+
60+
And the MainActivity uses this configuration:
3761

3862
```kotlin
39-
// URL of the PWA
40-
private val pwaUrl = "https://profullstack.com/pdf"
63+
// In MainActivity.kt
64+
private lateinit var pwaUrl: String
65+
66+
override fun onCreate(savedInstanceState: Bundle?) {
67+
super.onCreate(savedInstanceState)
68+
setContentView(R.layout.activity_main)
69+
70+
// Get API base URL from .env file
71+
pwaUrl = Config.getApiBaseUrl(this)
72+
73+
// ...rest of the code...
74+
}
4175
```
4276

4377
## Additional WebView Settings

desktop/README.md

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ A cross-platform desktop application that wraps the PDF Converter PWA in an Elec
44

55
## Features
66

7-
- Loads the PWA from https://profullstack.com/pdf
7+
- Loads the PWA from the URL specified in the project's root .env file
88
- Native desktop integration
99
- Cross-platform support (Windows, macOS, Linux)
1010
- Custom application menu
@@ -15,6 +15,7 @@ A cross-platform desktop application that wraps the PDF Converter PWA in an Elec
1515

1616
- Node.js 16.x or later
1717
- npm or yarn
18+
- dotenv (for .env file parsing)
1819

1920
## Getting Started
2021

@@ -72,15 +73,59 @@ This will generate:
7273
- Debian package (.deb)
7374
- RPM package (.rpm)
7475

75-
## Customization
76+
## Configuration
7677

77-
### PWA URL
78+
The app reads the PWA URL from the `API_BASE_URL` variable in the project's root `.env` file. This allows you to easily switch between different environments (development, staging, production) by modifying a single configuration file.
7879

79-
To change the URL of the PWA, modify the `pwaUrl` variable in `src/main.js`:
80+
### .env Configuration
81+
82+
In the project root's `.env` file:
83+
84+
```
85+
API_BASE_URL=https://profullstack.com/pdf
86+
```
87+
88+
### How It Works
89+
90+
The `config.js` file reads the API_BASE_URL from the .env file:
8091

8192
```javascript
82-
// URL of the PWA
83-
const pwaUrl = 'https://profullstack.com/pdf';
93+
// In src/config.js
94+
function getApiBaseUrl() {
95+
try {
96+
// Try to find the .env file in the project root
97+
const rootPath = path.resolve(__dirname, '../../');
98+
const envPath = path.join(rootPath, '.env');
99+
100+
if (fs.existsSync(envPath)) {
101+
// Parse .env file
102+
const envConfig = dotenv.parse(fs.readFileSync(envPath));
103+
104+
// Return API_BASE_URL if found
105+
if (envConfig.API_BASE_URL) {
106+
return envConfig.API_BASE_URL;
107+
}
108+
}
109+
110+
// Check environment variables as fallback
111+
// ...
112+
113+
// Return default URL if not found
114+
return DEFAULT_API_BASE_URL;
115+
} catch (error) {
116+
// Handle errors
117+
}
118+
}
119+
```
120+
121+
And the main.js uses this configuration:
122+
123+
```javascript
124+
// In src/main.js
125+
const { getApiBaseUrl } = require('./config');
126+
127+
// URL of the PWA - loaded from .env file
128+
const pwaUrl = getApiBaseUrl();
84129
```
85130

86131
### Application Icons
@@ -93,6 +138,7 @@ Replace the placeholder icon files in the `assets` directory with your own icons
93138
## Project Structure
94139

95140
- `src/main.js`: Main process script
141+
- `src/config.js`: Configuration module that reads from the .env file
96142
- `src/preload.js`: Preload script for secure renderer process
97143
- `assets/`: Application icons and resources
98144
- `package.json`: Project configuration and dependencies

desktop/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"electron": "^25.0.0",
1717
"electron-builder": "^24.0.0"
1818
},
19+
"dependencies": {
20+
"dotenv": "^16.0.3"
21+
},
1922
"build": {
2023
"appId": "com.profullstack.pdfconverter",
2124
"productName": "PDF Converter",

desktop/src/config.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const dotenv = require('dotenv');
4+
5+
// Default fallback URL
6+
const DEFAULT_API_BASE_URL = 'https://profullstack.com/pdf';
7+
8+
// Function to get API base URL from .env file
9+
function getApiBaseUrl() {
10+
try {
11+
// Try to find the .env file in the project root
12+
const rootPath = path.resolve(__dirname, '../../');
13+
const envPath = path.join(rootPath, '.env');
14+
15+
if (fs.existsSync(envPath)) {
16+
// Parse .env file
17+
const envConfig = dotenv.parse(fs.readFileSync(envPath));
18+
19+
// Return API_BASE_URL if found
20+
if (envConfig.API_BASE_URL) {
21+
return envConfig.API_BASE_URL;
22+
}
23+
}
24+
25+
// If .env file not found or API_BASE_URL not set, check environment variables
26+
if (process.env.API_BASE_URL) {
27+
return process.env.API_BASE_URL;
28+
}
29+
} catch (error) {
30+
console.error('Error reading .env file:', error);
31+
}
32+
33+
// Return default URL if .env file not found or error occurs
34+
return DEFAULT_API_BASE_URL;
35+
}
36+
37+
module.exports = {
38+
getApiBaseUrl
39+
};

desktop/src/main.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
const { app, BrowserWindow, Menu, shell } = require('electron');
22
const path = require('path');
3+
const { getApiBaseUrl } = require('./config');
34

4-
// URL of the PWA
5-
const pwaUrl = 'https://profullstack.com/pdf';
5+
// URL of the PWA - loaded from .env file
6+
const pwaUrl = getApiBaseUrl();
67

78
// Keep a global reference of the window object to prevent it from being garbage collected
89
let mainWindow;

0 commit comments

Comments
 (0)