Breaking the regression line into two pieces My X & Y variables are associated like this below and I am trying to fit a simple linear regression model (y ~ x , data= df) , to estimate β1 .

However I am not confident about extending the linear slope to values beyond 30. I want to restrict the regression slope to only x < 30
For x > 30 I want to slope to be horizontal so that β1 = 0. In other words breaking my linear regression line into two pieces x < 30 and x>30.

How can i do that ?

You can easily extend the solution by @Noah to a non-fixed break point, which you want to estimate from the data. There is the problem, however, that the fitted function $f$ is not differentiable in the break point $x_0$. It is
$$f(x,b_0,b_1,x_0)=\left\{\begin{array}{ll}
b_0 + b_1 x & \mbox{ for } x\leq x_0 \\
b_0+b_1 x_0 & \mbox{ for } x> x_0
\end{array}\right.$$
or, implemented in R
f <- function(x, b0, b1, x0) {
  ifelse(x < x0, b0 + b1*x, b0 + b1*x0)
}

This means that the R function for general least squares optimization nls might report a "singular gradient" error, e.g. for the following example:
set.seed(100)
n <- 50
x <- runif(n, 0, 40)
y <- f(x, 6, 2, 30) + rnorm(n, 0, 30)

fit <- nls(y ~ f(x, b0, b1, x0), start=list(b0=0, b1=1, x0=10))

This can be easily circumvented by using a more robust minimization algorithm that also works for non-differentiable functions, e.g. Nelder-Mead, which is the default algorithm in the R function optim:
# helper function defining the LSQ objective function
ssq <- function(par, x, y) {
  sum((y - f(x, par[1], par[2], par[3]))^2)
}

res <- optim(par=c(0,1,10), ssq, x=x, y=y)
if (res$convergence != 0) {
  stop("optim not converged")
}

# visualize result
# fitted parameters are stored in res$par
plot(x,y)
xr <- range(x)
xx <- seq(xr[1], xr[2], by=0.1)
lines(xx, f(xx, res$par[1], res$par[2], res$par[3]), col="blue")


