Channel server not working in the browser

Hello guys. In my Firefox browser, I can’t join a chat room for the server when I click on the ‘Join’ button.

I’m pretty sure I set up everything correctly in all of the files inside my arborchat app, and I don’t see any errors in the browser console, which I’ll share a screenshot.

Here are the files

serializers.py

from rest_framework import serializers
from arborfindr.models import User  
from arborchat.models import Room, Messenger, Arborist, ArboristProfile, Company, CompanyProfile
from django.contrib.auth import authenticate


class RegisterChatSerializer(serializers.ModelSerializer):
    password = serializers.CharField(style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = User
        fields = ['email', 'username', 'password']
        extra_kwargs = {
            'password': {'write_only': True}
        }
        
    def validate(self, valid):
        if valid['password'] != valid['password']:
            raise serializers.ValidationError({"password": "Passwords do not match."})
        return valid

    def create(self, validated_data):
        user = User.objects.create_user(
            email=validated_data['email'],
            username=validated_data['username'],
            password=validated_data['password']
        )
        return user
    
    
class LoginChatSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = User
        fields = ['email', 'username', 'password']
        extra_kwargs = {
            'password': {'write_only': True}
        }
    email = serializers.CharField(max_length=255)
    password = serializers.CharField(
        label =("Password"),
        style={'input_type': 'password'},
        trim_whitespace=False,
        max_length=128,
        write_only=True
    )

    def validate(self, data):
        email = data.get('email')
        password = data.get('password')

        if email and password:
            user = authenticate(request=self.context.get('request'),
                                email=email, password=password)

            if not user:
                msg = ('Invalid email/password')
                raise serializers.ValidationError(msg, code = 'Authorization')
        else:
            msg = ('Must include valid "email" and "password".')
            raise serializers.ValidationError(msg, code = 'Authorization')

        data['user'] = user
        return data
   
   

class RoomSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Room
        fields = ['name', 'online']
        
        
class MessengerSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Messenger
        fields = ['content', 'timestamp']
        
        
class ArboristSeriallizer(serializers.ModelSerializer):
    
    class Meta:
        model = Arborist
        fields = ['text']
        
        
class ArboristProfileSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = ArboristProfile
        fields = ['arborist_name', 'arborist_location', 'services_arborist', 'description', 
                  'size', 'arborist_logo', 'pricing']
        
        
class CompanySerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Company
        fields = ['text']
        

class CompanyProfileSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = CompanyProfile
        fields = ['company_name', 'company_location', 'services_company', 'company_description', 
                  'company_size', 'company_logo', 'website_link']

urls.py (app)

from django.urls import path
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from django.conf import settings
from django.contrib.auth import views as auth_views
from django.urls import path
from . import views
from .views import ChatLoginView, ChatRegisterView, ArboristProfileView, CompanyProfileView

urlpatterns = [
    path('', views.arborchat_home, name='arborchat-home'),
    path('arborist/register/', ChatRegisterView.as_view(), name='arborist-register'),  # Register API endpoint url
    path('arborist/login/', ChatLoginView.as_view(), name ='arborist-login'), # Login API endpoint url
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
    path('arborist/profile/', ArboristProfileView.as_view(), name='arborist-profile'),
    path('company/profile/', CompanyProfileView.as_view(), name='company-profile'),
    path('messenger/', views.messenger_room, name='messenger'),
    path('messenger/<str:room_name>/', views.room_view, name='messenger-room'),
    path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),

]

consumers.py

import json
from channels.consumer import AsyncConsumer

from channels.generic.websocket import AsyncJsonWebsocketConsumer
import base64


# Channel consumer for both chat room group

class ChatConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        
        # Join room group
        await self.channel_layer.group_add(self.room_group_name, self.channel_name)
        
        await self.accept()
        
        
    async def disconnect(self, close_code):

        # Leave room group
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)
        
    # Receive message from WebSocket
    
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        
        # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name, {'type': 'chat.message', 'message': message}
        )
        
    # Receive message from room group
    
    async def chat_message(self, event):
        message = event['message']
        
        # send message to websocket
        await self.send(text_data=json.dumps({'message': message}))
        
        
# Channel Consumer that consumed events for uploading/receiving image files in the message room

class UploadImageConsumer(AsyncJsonWebsocketConsumer):
    async def connect(self):
        await self.accept()
        

    async def disconnect(self, close_code):

        async def receive(self, bytes_data=None, text_data=None):
            if bytes_data:
            # Handles image file chunks (binary data)
            
                with open('image.jpg', 'rb') as f:
                    fcontent = f.read()
                await self.send(base64.b64encode(fcontent).decode('utf-8'))
            elif text_data:
                # Handles metadata (text data)
            
                await self.send(text_data=json.dumps({'message': text_data}))
            
            
    async def send_image(self, event):
        image_data = event['image_text']
        await self.send(bytes_data=image_data)
        ```

routing.py 

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
re_path(r’ws/arborchat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi())
]


views
 

from django.shortcuts import render

from arborchat.models import Room, Arborist

from arborfindr.models import User

from rest_framework.views import APIView

from rest_framework.decorators import authentication_classes, permission_classes

from rest_framework_simplejwt.authentication import JWTAuthentication

from rest_framework.response import Response

from rest_framework.permissions import IsAuthenticated, DjangoModelPermissionsOrAnonReadOnly, AllowAny

from django.contrib.auth import login

from .serializers import RoomSerializer, RegisterChatSerializer, LoginChatSerializer, ArboristProfileSerializer, CompanyProfileSerializer

from rest_framework.authtoken.models import Token

from rest_framework import status, generics, permissions

from rest_framework_simplejwt.tokens import RefreshToken

from drf_haystack.viewsets import HaystackViewSet

from haystack.query import SearchQuerySet

def arborchat_home(request):
return render(request, ‘arborchat/index.html’, {
‘channels’: Room.objects.values_list(‘room_name’, flat=True)
})
def index(request):
return render(request, ‘arborchat/index.html’, {
‘rooms’: Room.objects.all(),
})

def messenger_room(request, room_name):
room = Room.objects.first()
return render(request, ‘messenger.html’, {‘room’: room })

@authentication_classes([JWTAuthentication])
def room_view(request, room_name):
room, created = Room.objects.get_or_create(name=room_name)
return render(request, ‘messenger.html’, {‘room’: room})

API endpoint for Arborist login

@authentication_classes([JWTAuthentication])
class ChatLoginView(APIView):
authentication_classes = (JWTAuthentication,) # Keep as tuple if you prefer

def post(self, request, *args, **kwargs):
    serializer = LoginChatSerializer(data=request.data, context={'request': request})
    serializer.is_valid(raise_exception=True)
    user = serializer.validated_data['user']
    login(request, user)  # Corrected: Pass the request object
    token = Token.objects.create(user=user)  # Auth Token

    if user is not None:  # This block is now reachable
        # Generate token
        refresh = RefreshToken.for_user(user)
        access_token = str(refresh.access_token)
        return Response({
            'message': 'Successful login',
            'access_token': access_token,
            'refresh_token': str(refresh),
            "Token": token.key # Added auth token
        }, status=status.HTTP_200_OK)

    return Response({'error': 'Invalid email/password'}, status=status.HTTP_401_UNAUTHORIZED)  # Now reachable

@authentication_classes([JWTAuthentication])
class ChatRegisterView(generics.CreateAPIView):
queryset = User.objects.all()
serializer_class = RegisterChatSerializer
permission_classes = [permissions.AllowAny]

def post(self, request):
    serializer = RegisterChatSerializer(data=request.data, context={'request': request})
    if serializer.is_valid():
        serializer.save()
        return Response({
            'message': 'successfully registered',  }, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class ArboristProfileView(APIView):

permission_classes = [IsAuthenticated]
authentication_classes = [JWTAuthentication]
serializer_class = ArboristProfileSerializer
def get(self, request):
    user = request.user
    serializer = self.serializer_class(user)
    return Response(serializer.data)

def delete(self, request, *args, **kwargs):
    return self.destroy(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

class CompanyProfileView(APIView):

permission_classes = [IsAuthenticated]
authentication_classes = [JWTAuthentication]
serializer_class = CompanyProfileSerializer
def get(self, request):
    user = request.user
    serializer = self.serializer_class(user)
    return Response(serializer.data)

def delete(self, request, *args, **kwargs):
    return self.destroy(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

class SearchBarView(APIView):

model = Arborist
permission_classes = [IsAuthenticated]
serializer_classes = ArboristProfileSerializer
success_url = '/'
context_object_name = 'all_search_results'


def get(self):
    
   query = self.request.GET.get('search')
   results = SearchQuerySet().filter(content=query)

serialize results based on models

   serialized_results = []
   for result in results:
       if result.model == 'arborist':
           serializer = ArboristProfileSerializer(result.object)
       elif result.model == 'company':
           serializer = CompanyProfileSerializer(result.object)
       else:
           continue
       serialized_results.append(serializer.data)
   return Response(serialized_results)

index.html

{% load static %}

ArborHub messenger #arboristRoomSelect { height: 300px; }
Choose which messenger channel to join: You can create a new channel, if one hasn't been already created
Join
Current channels
</body>
```

messenger.html

{% load static %}

<!DOCTYPE html>

<html lang="en">
    <head>
    <title>ArborHub messenger</title>
        <link rel="icon" href="{% static 'favicon.ico' %}">
    <link rel="stylesheet" href="http://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
    <script src="http://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
   
    <style>
        #messageLog {
            height: 300px;
            background-color: #FFFFFF;
            resize: none;
        }

        #onlineArboristSelector {
            height: 300px;
        }
    </style>
</head>
<body>

    <textarea id='chat-text' cols='80' rows='30'></textarea>
    <input id='input' type='text' size='80'><br>
    <input id='submit' type='button' value='Send'>

    <div id='hello-world'></div>

    {{ room_name|json_script:'room-name'}}
    <script> 
        document.querySelector('#submit').onclick = function (e) {
            const messageInputDom = document.querySelector('#input');
            const message = messageInputDom.value;
            chatSocket.send(JSON.stringify({
                'message': message,
            }));
            messageInputDom.value = '';
        };
        const roomName = JSON.parse(document.getElementById('room-name').textContent);

        const chatSocket = new WebSocket(
            'ws://' +
            proxyLoc(location).host +
            '/ws/arborchat/' +
            roomName +
            '/'
        );

        chatSocket.onmessage = function (e) {
            const data = JSON.parse(e.data);
            console.log(data)
            document.querySelector('#hello-world').innerText = data.message
        }
    </script>
    <div class="container mt-3 p-5">
        <h2>ArborHub messenger</h2>
        <div class="row">
            <div class="col-12 col-md-8">
                <div class="mb-2">
                    <label for="messageLog">Room: #{{ room.name}}</label>
                    <textarea class="form-control" id="messageLog" readOnly></textarea>
                </div>
                <div class="input-group">
                    <input type="text" class="form-control" id="channelMessage" placeholder="Message here">
                    <div class="input-group-append">
                        <button class="btn btn-success" id="sendMessage" type="button">Send</button>
                    </div>
                </div>
            </div>
            <div class="col-12 col-md-4">
               <label for="onlineArboristSelector">Online arborists</label>
                <select multiple class="form-control" id="onlineArboristSelector">
                </select>
            </div>
        </div>
    </div>
 
</body>
</html>

Finally settings

ASGI_APPLICATION = "MyProject.asgi.application"

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

Let me know if you need additional files

hi
I think the root cause is that your “Join” link never actually hits the view (and so never renders messenger.html)—your URL pattern is malformed, and your template isn’t wiring the button to any JavaScript, so nothing happens when you click it.

I think this might help:

urlpatterns = [
    …
    path('messenger/<str:room_name>/', views.room_view, name='messenger-room'),
    …
]

Also, I think you need a small script to redirect on click and pass the correct context into messenger.html

Here is so far I can review with your description

Best Idea is to sit relaxedly with sound mind and read your file codes, its really helps. You can also use any debugger extension
Wish you best

1 Like

Maybe format your code when posting, it’s very hard to read. Otherwise, nobody would be to debug the code.

Format different files in different blocks.

Use “```” at both ends of code segments.(three ` characters.)

1 Like

Yeah I see what you mean, I thought I formatted it properly. I’ll fix it now

Thanks I’ll try that

Still has some unformatted code.

Yes, I know. I’ll get right on it

Hello guys. In my Firefox browser, I can’t join a chat room for the server when I click on the ‘Join’ button.

I’m pretty sure I set up everything correctly in all of the files inside my arborchat app, and I don’t see any errors in the browser console, which I’ll share a screenshot.

Here are the files

serializers.py

from rest_framework import serializers
from arborfindr.models import User  
from arborchat.models import Room, Messenger, Arborist, ArboristProfile, Company, CompanyProfile
from django.contrib.auth import authenticate


class RegisterChatSerializer(serializers.ModelSerializer):
    password = serializers.CharField(style={'input_type': 'password'}, write_only=True)

    class Meta:
        model = User
        fields = ['email', 'username', 'password']
        extra_kwargs = {
            'password': {'write_only': True}
        }
        
    def validate(self, valid):
        if valid['password'] != valid['password']:
            raise serializers.ValidationError({"password": "Passwords do not match."})
        return valid

    def create(self, validated_data):
        user = User.objects.create_user(
            email=validated_data['email'],
            username=validated_data['username'],
            password=validated_data['password']
        )
        return user
    
    
class LoginChatSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = User
        fields = ['email', 'username', 'password']
        extra_kwargs = {
            'password': {'write_only': True}
        }
    email = serializers.CharField(max_length=255)
    password = serializers.CharField(
        label =("Password"),
        style={'input_type': 'password'},
        trim_whitespace=False,
        max_length=128,
        write_only=True
    )

    def validate(self, data):
        email = data.get('email')
        password = data.get('password')

        if email and password:
            user = authenticate(request=self.context.get('request'),
                                email=email, password=password)

            if not user:
                msg = ('Invalid email/password')
                raise serializers.ValidationError(msg, code = 'Authorization')
        else:
            msg = ('Must include valid "email" and "password".')
            raise serializers.ValidationError(msg, code = 'Authorization')

        data['user'] = user
        return data
   
   

class RoomSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Room
        fields = ['name', 'online']
        
        
class MessengerSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Messenger
        fields = ['content', 'timestamp']
        
        
class ArboristSeriallizer(serializers.ModelSerializer):
    
    class Meta:
        model = Arborist
        fields = ['text']
        
        
class ArboristProfileSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = ArboristProfile
        fields = ['arborist_name', 'arborist_location', 'services_arborist', 'description', 
                  'size', 'arborist_logo', 'pricing']
        
        
class CompanySerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Company
        fields = ['text']
        

class CompanyProfileSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = CompanyProfile
        fields = ['company_name', 'company_location', 'services_company', 'company_description', 
                  'company_size', 'company_logo', 'website_link']

settings

ASGI_APPLICATION = "MyProject.asgi.application"

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}

consumers.py

from django.urls import path
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from django.conf import settings
from django.contrib.auth import views as auth_views
from django.urls import path
from . import views
from .views import ChatLoginView, ChatRegisterView, ArboristProfileView, CompanyProfileView

urlpatterns = [
    path('', views.arborchat_home, name='arborchat-home'),
    path('arborist/register/', ChatRegisterView.as_view(), name='arborist-register'),  # Register API endpoint url
    path('arborist/login/', ChatLoginView.as_view(), name ='arborist-login'), # Login API endpoint url
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
    path('arborist/profile/', ArboristProfileView.as_view(), name='arborist-profile'),
    path('company/profile/', CompanyProfileView.as_view(), name='company-profile'),
    path('messenger/', views.messenger_room, name='messenger'),
    path('messenger/<str:room_name>/', views.room_view, name='messenger-room'),
    path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),

routing.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r'ws/arborchat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi())

views

from django.shortcuts import render

from django.shortcuts import render

from arborchat.models import Room, Arborist

from arborfindr.models import User  

from rest_framework.views import APIView

from rest_framework.decorators import authentication_classes, permission_classes

from rest_framework_simplejwt.authentication import JWTAuthentication

from rest_framework.response import Response

from rest_framework.permissions import IsAuthenticated, DjangoModelPermissionsOrAnonReadOnly, AllowAny

from django.contrib.auth import login

from .serializers import RoomSerializer, RegisterChatSerializer, LoginChatSerializer, ArboristProfileSerializer, CompanyProfileSerializer

from rest_framework.authtoken.models import Token

from rest_framework import status, generics, permissions

from rest_framework_simplejwt.tokens import RefreshToken

from drf_haystack.viewsets import HaystackViewSet

from haystack.query import SearchQuerySet


def arborchat_home(request):
    return render(request, 'arborchat/index.html', {
        'channels': Room.objects.values_list('room_name', flat=True)
    })
def index(request):
    return render(request, 'arborchat/index.html', {
        'rooms': Room.objects.all(),
})
    
    
def messenger_room(request, room_name):
    room = Room.objects.first()
    return render(request, 'messenger.html', {'room': room })


@authentication_classes([JWTAuthentication])
def room_view(request, room_name):
    room, created = Room.objects.get_or_create(name=room_name)
    return render(request, 'messenger.html', {'room': room})


# API endpoint for Arborist login

@authentication_classes([JWTAuthentication])
class ChatLoginView(APIView):
    authentication_classes = (JWTAuthentication,)  # Keep as tuple if you prefer

    def post(self, request, *args, **kwargs):
        serializer = LoginChatSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        login(request, user)  # Corrected: Pass the request object
        token = Token.objects.create(user=user)  # Auth Token

        if user is not None:  # This block is now reachable
            # Generate token
            refresh = RefreshToken.for_user(user)
            access_token = str(refresh.access_token)
            return Response({
                'message': 'Successful login',
                'access_token': access_token,
                'refresh_token': str(refresh),
                "Token": token.key # Added auth token
            }, status=status.HTTP_200_OK)

        return Response({'error': 'Invalid email/password'}, status=status.HTTP_401_UNAUTHORIZED)  # Now reachable
    
    
@authentication_classes([JWTAuthentication])
class ChatRegisterView(generics.CreateAPIView):  
    queryset = User.objects.all()
    serializer_class = RegisterChatSerializer
    permission_classes = [permissions.AllowAny]
 
    def post(self, request):
        serializer = RegisterChatSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response({
                'message': 'successfully registered',  }, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ArboristProfileView(APIView):
    
    permission_classes = [IsAuthenticated]
    authentication_classes = [JWTAuthentication]
    serializer_class = ArboristProfileSerializer
    def get(self, request):
        user = request.user
        serializer = self.serializer_class(user)
        return Response(serializer.data)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
    
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
        
        
class CompanyProfileView(APIView):
    
    permission_classes = [IsAuthenticated]
    authentication_classes = [JWTAuthentication]
    serializer_class = CompanyProfileSerializer
    def get(self, request):
        user = request.user
        serializer = self.serializer_class(user)
        return Response(serializer.data)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
    
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    
    
class SearchBarView(APIView):
    
    model = Arborist
    permission_classes = [IsAuthenticated]
    serializer_classes = ArboristProfileSerializer
    success_url = '/'
    context_object_name = 'all_search_results'
    
    
    def get(self):
        
       query = self.request.GET.get('search')
       results = SearchQuerySet().filter(content=query)
   
   # serialize results based on models
   
       serialized_results = []
       for result in results:
           if result.model == 'arborist':
               serializer = ArboristProfileSerializer(result.object)
           elif result.model == 'company':
               serializer = CompanyProfileSerializer(result.object)
           else:
               continue
           serialized_results.append(serializer.data)
       return Response(serialized_results)

index.html

{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <title>ArborHub messenger</title>
    <link rel="icon" href="{% static 'favicon.ico' %}">
    <link rel="stylesheet" href="http://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
    <script src="http://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
    <style>
        #arboristRoomSelect {
            height: 300px;
        }
    </style>
</head>
<body>
   <div class="container mt-3 p-5">
    <div class="row">
        <div class="col-12 col-md-8">
            <div class="mb-2">
                <label for="roomInput">Choose which messenger channel to join:</label>
                <input type="text" class="form-control" id="roomInput" placeholder="Messenger channel name">
                <small id="roomInputHelp" class="form-text text-muted">You can create a new channel, if one hasn't been already created</small>
            </div>
            <button type="button" id="roomJoin" class="btn btn-success">Join</button>
        </div>
        <div class="col-12 col-md-4">
            <label for="roomSelect">Current channels</label>
            <select multiple class="form-control" id="roomSelect">
                {% for channel in channels %}
                    <option>{{ channel }}</option>
                {% endfor %}
            </select>
        </div>
    </div>
</div> <!-- Make sure this closes the outer container -->

    </body>
</html>

Let me know if you need additional files

I pasted the revised files in my response. It’s formatted better

So basically the ‘Join’ button needs to have an action, e.g. redirect? I fixed the url path problem btw

Ok.

What is your current problem?

The ‘Join’ button for my chat server page in the browser won’t redirect to the chat room. adyaprasad already helped me with my urls file.

But he mentioned adding a redirection in messenger.html, I’m just not sure what to add or where in this html file

Ok. I understand. But problem is in your index l.html. Please format it. You can edit your post and format it. Then I will show you how to solve the problem.

Nobody can read html like this easily.

Okay I added index.html formatted

Is this your full template code?

Affirmative, it is index.html

Yes it’s the complete file

Ok. Make a javascript function, which triggers on click join button, which takes selected chat name from the input and build the required url like messenger/<str:room_name>/. Then set the window url.

Like this?

const button = document.getElementById('myButton');

button.addEventListener('click', function() {
  console.log('Button clicked!');
});

Yes. Replace the id with roomJoin. Replace the console log with


url = `messenger/${document.getElementById('roomInput').value}`;

proxyLocation(window).href = url;



.