I need to update files in my public GitHub repo directly from a web page using only vanilla JavaScript. No external libraries like octokit allowed. I want to modify a JSON file in my repository through the GitHub API.
I already have my personal access token and client credentials set up. GitHub documentation mostly shows octokit examples, but since they only “recommend” it, there should be other ways to do this with plain JavaScript.
I tried something like this but it didn’t work:
let appId = "MY_APP_ID";
let accessToken = "PERSONAL_ACCESS_TOKEN";
fetch(`https://api.github.com/repos/username/repo-name/data.json?client_id=${appId}&access_token=${accessToken}`, {
method: "POST",
headers: { 'Content-Type': 'application/json'},
body: JSON.stringify('New content for the file')
}).then(res => {
console.log("Done! Response:", res);
});
After some testing, I found a working solution that doesn’t have CORS issues even from localhost. Here’s what worked:
// Configuration
const repoOwner = "myUsername";
const repoName = "myProject";
const filePath = "data.json";
const authToken = "ghp_tokenhere";
// Content to write
const fileContent = {
name: "Product Name",
category: "Electronics",
cost: 199.99
};
// Get current file SHA
async function getCurrentSha() {
try {
const response = await fetch(
`https://api.github.com/repos/${repoOwner}/${repoName}/contents/${filePath}`,
{
method: "GET",
headers: {
"Authorization": `Bearer ${authToken}`,
"Accept": "application/vnd.github+json",
"Content-Type": "application/json"
}
}
);
if (!response.ok) {
if (response.status === 404) return null;
throw new Error(`Error getting SHA: ${response.statusText}`);
}
const fileData = await response.json();
return fileData.sha;
} catch (err) {
console.error("SHA fetch error:", err);
return null;
}
}
// Update file content
async function modifyRepoFile() {
try {
const currentSha = await getCurrentSha();
const encodedContent = btoa(JSON.stringify(fileContent, null, 2));
const requestBody = {
message: "Updated data.json from web interface",
content: encodedContent,
sha: currentSha
};
const response = await fetch(
`https://api.github.com/repos/${repoOwner}/${repoName}/contents/${filePath}`,
{
method: "PUT",
headers: {
"Authorization": `Bearer ${authToken}`,
"Accept": "application/vnd.github+json",
"Content-Type": "application/json"
},
body: JSON.stringify(requestBody)
}
);
if (!response.ok) {
const errorInfo = await response.json();
throw new Error(`Update failed: ${errorInfo.message}`);
}
const updateResult = await response.json();
console.log("Success! Commit link:", updateResult.commit.html_url);
} catch (err) {
console.error("File update error:", err);
}
}
modifyRepoFile();
This approach works perfectly with just vanilla JavaScript and no external dependencies.