Path to file: getting to the root directory

Hello and thanks for reading and assisting.
Based on @[Kris Koishigawa]'s https://www.freecodecamp.org/news/reusable-html-components-how-to-reuse-a-header-and-footer-on-a-website/
My site structure is:
(site) . . . . . . . . Drive “Z:”
├── style.css
├── test.html . . . . will become index.html
├── level2 . . . . . . .subdirectory, will have level3/test3.html
│ . . . . . └── test2.html
└── components
. . . . . . ├── footer.js
. . . . . . └── HappyBook.png
My problem is getting HappyBook.png to display in test2.html without having a separate footer.js for each level of sub-directories.
Thank you.
– Fred (not smart enough to do this on CodePen)
style.css:

*  {
 margin: 0;
 padding: 0;
 box-sizing: border-box;
}

html, body {
 height: 100%;
}

body {
 color: #333;
 font-family: sans-serif;
 display: flex;
 flex-direction: column;
}

main {
 flex: 1 0 auto;
}
img {
 border: 2px solid black;
}

test.html

<!DOCTYPE html> <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet" type="text/css">
    <script src="components/footer.js"></script>
    <title>Site-Root test.html</title>
  </head>
  <body>
    <main>
      <h1>Using JS for the Footer</h1>
      <p>This is a modification of https://www.freecodecamp.org/news/reusable-html-components-how-to-reuse-a-header-and-footer-on-a-website/</p>
      <ul>
        <li><A href="level2/test2.html">level2/test2.html</A></li>
      </ul>
      <pre>
        I used the DOS command "SUBST z: D:\Projects\Templates" 
        so that this file appears as Z:\test.html.
        This appears as expected with Firefox 108.0.1

          The footer are called as:
        &lt;script src="components/footer.js">
      </pre>
      <img src="components/HappyBook.png" alt="Happy Book" style="width: 60px; height: 60px;" >
    </main>
    <footer-component></footer-component>
  </body>
</html>

level2/test2.html

<!DOCTYPE html> <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet" type="text/css">
    <script src="../components/footer.js"></script>
    <title>level2\test2.html</title>
  </head>
  <body>
    <main>
      <h1>Using JS for the Footer</h1>
      <p>This is a modification of https://www.freecodecamp.org/news/reusable-html-components-how-to-reuse-a-header-and-footer-on-a-website/</p>
      <ul>
        <li><a href="../test.html">back to Site-Root test.html</a> "../test.html"</li>
      </ul>
      <pre>
        This file appears as Z:\level2\test2.html.
        The footer are called as:
        &lt;script src="../components/footer.js">
        It works, however the 
        &lt;img src="components/HappyBook.png"> inside ../components/footer.js
        is not seen. 
      </pre>
      <h4>Please suggest a way to make this work.</h4>
    </main>
    <footer-component></footer-component>
  </body>
</html>

components/footer.js

const footerTemplate = document.createElement('template');

footerTemplate.innerHTML = `
  <style>
    footer {
      height: 60px;
      padding: 0 10px;
      list-style: none;
      display: flex;
      flex-shrink: 0;
      justify-content: space-between;
      align-items: center;
      background-color: #dfdfe2;
    }

    ul {
      padding: 0;
    }
    
    ul li {
      list-style: none;
      display: inline;
    }
    
    a {
      margin: 0 15px;
      color: inherit;
      text-decoration: none;
    }
    
    a:hover {
      padding-bottom: 5px;
      box-shadow: inset 0 -2px 0 0 #333;
    }
    
    img {
      border: 2px solid black;
    }
  </style>
  <footer>
    <ul>
      <li><img src="components/HappyBook.png" alt="happy book" style="width: 40px; height=40px"></li>
      <li><a href="about.html">About</a></li>
      <li><a href="work.html">Work</a></li>
      <li><a href="contact.html">Contact</a></li>
    </ul>
  </footer>
`;

class Footer extends HTMLElement {
  constructor() {
    super();
  }

  connectedCallback() {
    const shadowRoot = this.attachShadow({ mode: 'closed' });
    shadowRoot.appendChild(footerTemplate.content);
  }
}

customElements.define('footer-component', Footer);

The dot dot …/ is how you navigate up one directory.
If you want to navigate up twice then write …/…/
I cannot tell by your description where you want to go exactly but my interpretation of what you wrote was:
…/components/HappyBook.png

(That is, go up one directory then go down into components directory to find the file)

Thank you, Hanaa. @hbar1st ,
My problem is seen in test2/html. I call …/components/footer.js which then calls components/HappyBook.png.
Both reside in /components. Footer.js now looks inside of \level2\components (proven by a test) and not where the image should reside.

With PHP, define(“LOCAL_PATH_ROOT”, $_SERVER[“DOCUMENT_ROOT”]); would give a solid reference where everything could be pinned.

One work-around is a separate footer,js for each: site root level, root/level2, root/level2/level3 .

Changes to 3 files is better than 30, but not as good as changing only one.

Thanks.

unfortunately I have no idea what you are trying to do still.
(I’m not familiar with the project you are working on ).

If the png file is in the same directory as the js file and the js file is the one that needs it then you would need ./HappyBook.png
(since it is the same directory).
If the html file is the one that needs it then you need to set the relative path based on where the html is to the png file.
(I’m sorry I still am not clear where the html is or where the png file is based on the info shared so far but I hope you can modify the relative path to the png to accomodate whatever file setup you have)

Hanaa @hbar1st ,
The code for each file is in the original post.
The .png and .js are both in the same directory (components).

It appears to me that
if (site-root)/level2/test2.html calls …/components/footer.js,
then footer.js does not look in …/components,
but instead looks in …/level2/components
to find the .png.

Then that means the path is relative to the html file.

(site-root)/level2/test2.html

Assume you are here, what is the relative path from here to the png file and use that.

(site-root)/test.html calls
(site-root)/components/footer.js calls its sibling
(site-root)/components/HappyBook.png and all is well.

(site-root)/level2/test2.html calls
…/components/footer.js which I hope would call its sibling .

However, …/components/footer.js appears to actually call
(site-root)/level2/components/HappyBook.png.

What happens if you change this line to use `…/components/HappyBook.png” ?

Yes, that works. That is why I wrote that:

One each footer.js for each level:
All
(site-root)/*.html calls
(site-root)/components/footer.js which calls its sibling
(site-root)/components/HappyBook.png

Then
(site-root)/anylevel-1/*.html calls
…/components/footer.js which must call
…/components/HappyBook.png

And
(site-root)/anylevel-1/anylevel-2/*.html calls
…/…/components/footer.js which has to call
…/…/components/HappyBook.png

Out of curiosity, why did you decide on this directory structure?
Normally all assets like images are kept in one directory, all source code in one (other) directory.

And is this ‘vanilla’ JavaScript only? (I believe if you are using Node.js for eg that you can use the Path module to get the full path of the application https://nodejs.org/api/path.html

This was quick and dirty just to form the question. My real structure will be like:
(Site Name)
├── menu.html
├── sitemap.html
├── subject-1
│ ├── welcome
│ ├── secutity
│ └── (several more)
├── subject-2
│ ├── welcome
│ ├── secutity
│ └── (several more)
├── includes
│ ├── images/ All of the images used on this site.
│ ├── css/ style.css.
│ └── js/ header and footer javascripts
└── (more?)
The Welcomes are sub-menus.
All images will be in (Site Name)/includes/image.
All .js and .css in (Site Name)/includes/css-js.
( I am opened to suggestions)
----±—
I don’t know enough about JavaScript to answer. These were taken from
Kris Koishigawa’s https://www.freecodecamp.org/news/reusable-html-components-how-to-reuse-a-header-and-footer-on-a-website/ as I want to standardize my header and footer. This seems to be the best way for me to do this client-side only (no server side SSI or PHP needed).

I want this to be as close to plain ‘vanilla’ HTML-5 CSS-3 as possible.
This bit of .js is best I have found to date.

Thanks, @hbar1st

In the footer.js try to issue this command (in a line above the line that sets the innerHTML)

alert(window.location.pathname);

This should pop up a window with the script’s path.
If this works, then you can use this variable to set the src path for your ping more dynamically.

test.html calls
<script src=“components/footer.js”></script>
and shows:

file://
/Z:/test.html

and
level2/test2.html calls
<script src=“…/components/footer.js”></script>
and shows:

file://
/Z:/level2/test2.html

These are paths of the calling files.

I don’t have a clue on how to use this to keep from changing
<img src=“components/HappyBook.png”> to
<img src=“…/components/HappyBook.png”> for level2/test2.html.

I will check back in the morning.
Thanks for your help, Hanaa @hbar1st !
( Good night! )

Good morning and thank you, Randell @camperextraordinaire .
For whatever reason that does not work for me. That goes down to the “real” root drive (D:) and not the virtual drive (Z:).
The same problem exists for the for the links.
file:///Z:/test.html calling “components/footer.js” shows “Z:about.html”.
file:///Z:/level2/test2.html calling “…/components/footer.js” shows “Z:level2/about.html”.

When I can solve one of the problems, the solution will work for the other.
A work-around would be footer.js for the root level and footer-lvl-2.js for second level use.

Thank you, @camperextraordinaire
I moved it and it works under localhost (xampp ) - as long as it is in the root (htdocs). It does not work from within a folder within htdocs (htdocs/test) !

I would like for this to work under a browser without the need of connection.

sorry to interject but why would moving the image directory somewhere that is not root affect the absolute path working or not? (I have a feeling you understood something from OP’s response that I didn’t so that’s why I’m asking).
Whether the component dir is a direct child of root or not, if the path is fixed, shouldn’t the OP be able to specify the path either way?

Don’t apologize, Hanaa. The only wrong questions are the ones not asked.

Ideally, I would like to include a header and footer with links using only HTML-5 and CSS-3, which I am still learning.
I came across this Kris Koishigawa’s method (see the original post) and tried to adopt that.

I’ve got to to some ‘real life’ things so will be back in a few hours.
Thank you both, @camperextraordinaire @hbar1st
– Fred

I tested a solution using document.location.toString() on linux, but I imagine the following could work on a Window’s machine.
At the top of the footer.js file, put:

const rootDir = 'file:///D:/'; // might have to use 'file:\\D:\`

Then in the template literal, the img element would be:

<img src="${rootDir}components/HappyBook.jpg" alt="happy book" style="width: 40px; height=40px">

Thank you, @camperextraordinaire !!!
For the case of Drive Z:, footer.js beginning with:

const footerTemplate = document.createElement('template');
 const rootDir = 'file:///Z:/'; 
footerTemplate.innerHTML = ` 

and

      <li><img src="${rootDir}components/HappyBook.png" alt="..."></li>
      <li><a href="${rootDir}about.html">About</a></li>

worked for me!
For localhost, I used:

 const rootDir = 'http://localhost/test-2/'; 

and it works as well.
Thank you!,
And I thank @hbar1st as well!

PS: Please let me know if you think of any other way to include files with HTML - CSS only.
Thanks again.

My localhost demonstrates the same problem:
without the ~~ const rootDir ~~~

<a href="/about.html">About</a>

looks for C:\about.html :frowning: