We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Phoenix LiveView is a powerful library that enables real-time interactivity in web applications, without requiring complex JavaScript frameworks. It's especially loved for its ability to keep everything dynamic and maintainable in Elixir, while still allowing fine-tuned control with JavaScript when necessary.
In some cases, you'll want to enhance the user experience by adding simple JavaScript functionalities. For example, you may want to make all links inside a specific section open in a new tab. In jQuery, this is a breeze, but you can do it equally well in vanilla JavaScript in a Phoenix LiveView app by using LiveView hooks. Let's walk through how to do this.
Step 1: The JavaScript Code
If you're familiar with jQuery, you might recognize the following snippet that opens all links inside an element with
id="content"
in a new tab:
$(function(){
$("#content a").attr("target", "_blank");
});
However, in a modern Phoenix LiveView app, we aim to avoid jQuery in favor of vanilla JavaScript. So, the same functionality in vanilla JavaScript looks like this:
document.addEventListener("DOMContentLoaded", function() {
var links = document.querySelectorAll("#content a");
links.forEach(function(link) {
link.setAttribute("target", "_blank");
});
});
This code selects all anchor (<a>
) elements inside an element with the id="content"
and sets their target
attribute to _blank
, making them open in a new tab when clicked.
However, Phoenix LiveView dynamically updates the DOM, so just adding this JavaScript on page load won't suffice because the links may be added or updated later by LiveView. To handle this dynamically, we'll use LiveView Hooks.
Step 2: Introducing Phoenix LiveView Hooks
LiveView Hooks allow you to execute JavaScript when specific LiveView components are mounted or updated. This is incredibly useful when you want to manipulate the DOM after LiveView has updated the content.
Let's create a hook that ensures all links inside the #content
element will always open in a new tab, even when the
content changes dynamically.
Step 3: Creating the LiveView Hook
We'll start by defining a new JavaScript hook. Create a hooks.js
file (or add this to an existing file, such as
app.js
), and include the following code:
let hooks = {};
hooks.OpenLinksInNewTab = {
mounted() {
this.updateLinks();
},
updated() {
this.updateLinks();
},
updateLinks() {
var links = this.el.querySelectorAll("a");
links.forEach(function(link) {
link.setAttribute("target", "_blank");
});
}
};
export default hooks;
What's Happening Here?
mounted()
: This function runs when the element is first added to the DOM. We callupdateLinks()
here to ensure that when the component is initially rendered, all links inside it will open in a new tab.updated()
: LiveView can update components without reloading the whole page. To ensure that any newly rendered links behave the same way, we also callupdateLinks()
whenever the component is updated.updateLinks()
: This helper function selects all anchor tags within the element and sets theirtarget
attribute to_blank
, making sure all links open in a new tab.
Step 4: Adding the Hook to Your LiveView App
Now, we need to attach this hook to our LiveView socket connection. In your app.js
file, modify it to load your hooks
and connect them to the LiveSocket.
import { Socket } from "phoenix";
import { LiveSocket } from "phoenix_live_view";
import hooks from "./hooks"; // Adjust the path based on where you store hooks.js
let liveSocket = new LiveSocket("/live", Socket, { hooks: ooks });
liveSocket.connect();
This code registers the Hooks
object (containing the OpenLinksInNewTab
hook) with the LiveSocket connection.
Step 5: Using the Hook in Your LiveView Template
To enable this hook in your LiveView template, attach it to the DOM element where your links reside. For example, you might add it like this:
<div id="content" phx-hook="OpenLinksInNewTab">
<a href="https://example.com">Example</a>
<!-- More links here -->
</div>
This ensures that the OpenLinksInNewTab
hook is applied to the #content
element, and every time LiveView updates
this section, the hook will run and update the links.
Step 6: Testing the Functionality
To see it in action:
- Navigate to a page in your Phoenix app that uses this LiveView.
- Inspect the links inside the
#content
element to ensure they now have thetarget="_blank"
attribute. - Click on any link, and it should open in a new tab.
Conclusion
By leveraging Phoenix LiveView Hooks, we can easily integrate dynamic JavaScript behavior like opening links in a new tab. This approach allows you to enhance your LiveView apps without compromising on the core benefits of server-rendered interactivity.
Not only does this method keep your JavaScript minimal, but it also ensures compatibility with the LiveView lifecycle, making it the ideal way to manage dynamic content changes in a modern Phoenix application.
Whether you're working with links, form elements, or other dynamic content, LiveView hooks provide an elegant way to extend functionality while maintaining performance and simplicity.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.