Making the link work?

If I’m making a social media site for example how do I make the links do what there suppose to do like, edit my profile or upload picture?

So far I just got the AI to make the look of it so far.

2 Likes

Whether you just need to create visual links on the page or build the entire SNS site system from scratch makes a world of difference in difficulty…:sweat_smile:


A link “works” only when two things exist.

  1. The thing you click is the right HTML element.
  2. The destination or action behind it is real.

For a social site, “Edit profile” and “Upload picture” are not just styling. They are routes, forms, API endpoints, and storage.

1) Link vs button

  • Use <a href="..."> when the click should go to a URL. The href is what makes it an actual link. (MDN Web Document)
  • Use <button> when the click should do an action like save, upload, open a dialog. (MDN Web Document)

Beginner rule:

  • Edit profile often starts as a link to a settings page.
  • Save and Upload are buttons that send data to your server.

2) “Edit profile” working end to end

Step A. Make the click go somewhere real

Basic HTML:

<a href="/settings/profile">Edit profile</a>

Now you must make /settings/profile exist.

Two common setups:

  • Multi-page site: you actually have a page/file served there.
  • Single-page app (React Router etc.): the client router renders a page for that path. If refresh breaks with a 404, your host needs a rewrite rule. This is the classic SPA pitfall. (Stack Overflow)

Step B. Put a form on that page

<form id="profileForm">
  <input name="displayName" placeholder="Display name" />
  <textarea name="bio" placeholder="Bio"></textarea>
  <button type="submit">Save</button>
</form>

Step C. On save, call an API endpoint

Use fetch and check response.ok. fetch() does not automatically “throw” on HTTP errors like 404. (MDN Web Document)

<script>
  document.getElementById("profileForm").addEventListener("submit", async (e) => {
    e.preventDefault();
    const data = Object.fromEntries(new FormData(e.target));

    const res = await fetch("/api/me", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });

    if (!res.ok) return alert("Save failed");
    alert("Saved");
  });
</script>

Step D. Backend updates the logged-in user

Your server needs something like:

  • PATCH /api/me → validate input → update database row for the current user

Security pitfall to avoid:

  • Do not let people edit other users by changing an id like /api/users/123. That is an IDOR risk. (OWASP Cheat Sheet Series)

3) “Upload picture” working end to end

Uploads are not normal links. They are file inputs plus a request.

Step A. Let the user pick a file

<input type="file"> is the standard control. ([MDN Web Document][6])

<input id="avatar" type="file" accept="image/*" />
<button id="uploadBtn" type="button">Upload</button>

Step B. Send the file with FormData

FormData builds the request body in the same format as a form using multipart/form-data. (MDN Web Document)

<script>
  document.getElementById("uploadBtn").addEventListener("click", async () => {
    const file = document.getElementById("avatar").files[0];
    if (!file) return alert("Choose a file first");

    const fd = new FormData();
    fd.append("avatar", file); // field name "avatar" must match the backend
    const res = await fetch("/api/me/avatar", { method: "POST", body: fd });

    if (!res.ok) return alert("Upload failed");
    alert("Uploaded");
  });
</script>

Note:

  • Forms use multipart/form-data for file uploads. (MDN Web Document)
  • When you send FormData with fetch, the browser sets the correct multipart headers for you. (Common beginner mistake is forcing Content-Type manually.)

Step C. Backend must parse multipart uploads

Example if you use Node + Express: use Multer. It is made for multipart/form-data and will not process non-multipart requests. (Express)

// deps: npm i express multer
import express from "express";
import multer from "multer";

const app = express();
const upload = multer({ dest: "uploads/" });

app.post("/api/me/avatar", upload.single("avatar"), (req, res) => {
  // req.file is the uploaded file
  // Save path or URL into the logged-in user's profile in your DB
  res.json({ ok: true });
});

app.listen(3000);

Step D. Store it somewhere real

For a beginner project, saving to uploads/ is fine.
For a real app, you usually store images in object storage and store the URL in the database.

Security basics for uploads:

  • Validate file type and size.
  • Store safely.
    OWASP’s file upload checklist is the standard reference. (OWASP Cheat Sheet Series)

4) Debugging checklist when “it still doesn’t work”

  1. Does your “link” have a real href? (MDN Web Document)

  2. Are you using a <button> for actions? (MDN Web Document)

  3. DevTools → Network:

    • Did a request happen?
    • Did it return 200–299?
    • If not, remember fetch does not throw on 404 by default. (MDN Web Document)
  4. If routing works only when clicking but breaks on refresh, it is likely the SPA rewrite problem. (Stack Overflow)

  5. For uploads, confirm the backend is parsing multipart. (Express)

Recommended reading (tight and practical)

Summary

  • Links navigate. Buttons act. href and real routes matter. (MDN Web Document)
  • “Edit profile” = settings route + form + API call + DB update.
  • “Upload picture” = file input + FormData + multipart parsing backend + storage. ([MDN Web Document][6])
  • Use DevTools Network and check response.ok. (MDN Web Document)
2 Likes